mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 20:10:17 +00:00
Compare commits
33 Commits
5.0.0-BETA
...
4.18.0-ALP
Author | SHA1 | Date | |
---|---|---|---|
bd21feffc4 | |||
5b324f695c | |||
9caed10488 | |||
83945ff0a0 | |||
ef45180b80 | |||
941fd03998 | |||
1af8da3c1f | |||
a5985dcf7d | |||
183d1f4038 | |||
08ee825d91 | |||
337a254768 | |||
a31e3331fd | |||
acebbeed16 | |||
e0fdbe6eb1 | |||
cc8660629b | |||
e7e19abe85 | |||
5f9e0081fd | |||
b266f45152 | |||
14f141fab2 | |||
daff955bc4 | |||
0022d82779 | |||
7cad9be0d2 | |||
2f862a552a | |||
590f6dad08 | |||
9564c81582 | |||
3de7a8c27f | |||
d376399b7f | |||
e2071e59c8 | |||
8e280ebb8b | |||
fa7c38276c | |||
b13e97de3d | |||
328b87fc18 | |||
acaa1a9ce1 |
10
.github/workflows/build-docker-image.yml
vendored
10
.github/workflows/build-docker-image.yml
vendored
@ -30,20 +30,20 @@ jobs:
|
||||
id: tag-name
|
||||
run: |
|
||||
VERSION=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
|
||||
echo ::set-output name=TAG_NAME::$VERSION
|
||||
echo ::set-output name=MAJOR::$(echo $VERSION | cut -d. -f1)
|
||||
echo ::set-output name=MINOR::$(echo $VERSION | cut -d. -f1-2)
|
||||
echo TAG_NAME=$VERSION >> $GITHUB_OUTPUT
|
||||
echo MAJOR=$(echo $VERSION | cut -d. -f1) >> $GITHUB_OUTPUT
|
||||
echo MINOR=$(echo $VERSION | cut -d. -f1-2) >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download new release information
|
||||
run: curl -f -L ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.tag-name.outputs.TAG_NAME }}/build_info.json -o new_build_info.json
|
||||
|
||||
- name: Detect channel
|
||||
id: channel
|
||||
run: echo ::set-output name=CHANNEL::$(jq -r '.channel' new_build_info.json)
|
||||
run: echo CHANNEL=$(jq -r '.channel' new_build_info.json) >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Get name of Docker repository name
|
||||
id: docker-repo-name
|
||||
run: echo ::set-output name=NAME::$(echo "${GITHUB_REPOSITORY,,}")
|
||||
run: echo NAME=$(echo "${GITHUB_REPOSITORY,,}") >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build image for tag
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
|
2
.github/workflows/discord-release-notify.yml
vendored
2
.github/workflows/discord-release-notify.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
||||
|
||||
- name: Get actual tag name
|
||||
id: tag-name
|
||||
run: echo ::set-output name=TAG_NAME::$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
|
||||
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run webhook post script
|
||||
run: php .github/workflows/discord-release-embed.php ${{ github.repository }} ${{ steps.tag-name.outputs.TAG_NAME }} ${{ github.token }} ${{ secrets.DISCORD_RELEASE_WEBHOOK }} ${{ secrets.DISCORD_NEWS_PING_ROLE_ID }}
|
||||
|
14
.github/workflows/draft-release.yml
vendored
14
.github/workflows/draft-release.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
run: |
|
||||
BUILD_NUMBER=$((2000+$GITHUB_RUN_NUMBER)) #to stay above jenkins
|
||||
echo "Build number: $BUILD_NUMBER"
|
||||
echo ::set-output name=BUILD_NUMBER::$BUILD_NUMBER
|
||||
echo BUILD_NUMBER=$BUILD_NUMBER >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Minify BedrockData JSON files
|
||||
run: php vendor/pocketmine/bedrock-data/.minify_json.php
|
||||
@ -51,12 +51,12 @@ jobs:
|
||||
- name: Get PocketMine-MP release version
|
||||
id: get-pm-version
|
||||
run: |
|
||||
echo ::set-output name=PM_VERSION::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BASE_VERSION;')
|
||||
echo ::set-output name=MCPE_VERSION::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\network\mcpe\protocol\ProtocolInfo::MINECRAFT_VERSION_NETWORK;')
|
||||
echo ::set-output name=PM_VERSION_SHORT::$(php -r 'require "vendor/autoload.php"; $v = explode(".", \pocketmine\VersionInfo::BASE_VERSION); array_pop($v); echo implode(".", $v);')
|
||||
echo ::set-output name=PM_VERSION_MD::$(php -r 'require "vendor/autoload.php"; echo str_replace(".", "", \pocketmine\VersionInfo::BASE_VERSION);')
|
||||
echo ::set-output name=CHANGELOG_SUFFIX::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BUILD_CHANNEL === "stable" ? "" : "-" . \pocketmine\VersionInfo::BUILD_CHANNEL;')
|
||||
echo ::set-output name=PRERELEASE::$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BUILD_CHANNEL === "stable" ? "false" : "true";')
|
||||
echo PM_VERSION=$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BASE_VERSION;') >> $GITHUB_OUTPUT
|
||||
echo MCPE_VERSION=$(php -r 'require "vendor/autoload.php"; echo \pocketmine\network\mcpe\protocol\ProtocolInfo::MINECRAFT_VERSION_NETWORK;') >> $GITHUB_OUTPUT
|
||||
echo PM_VERSION_SHORT=$(php -r 'require "vendor/autoload.php"; $v = explode(".", \pocketmine\VersionInfo::BASE_VERSION); array_pop($v); echo implode(".", $v);') >> $GITHUB_OUTPUT
|
||||
echo PM_VERSION_MD=$(php -r 'require "vendor/autoload.php"; echo str_replace(".", "", \pocketmine\VersionInfo::BASE_VERSION);') >> $GITHUB_OUTPUT
|
||||
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 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
|
||||
|
23
.github/workflows/main.yml
vendored
23
.github/workflows/main.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.27, 8.1.14, 8.2.1]
|
||||
php: [8.0.28, 8.1.16, 8.2.3]
|
||||
|
||||
steps:
|
||||
- name: Build and prepare PHP cache
|
||||
@ -21,7 +21,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "5"
|
||||
pm-version-major: "4"
|
||||
|
||||
phpstan:
|
||||
name: PHPStan analysis
|
||||
@ -32,7 +32,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.27, 8.1.14, 8.2.1]
|
||||
php: [8.0.28, 8.1.16, 8.2.3]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -42,7 +42,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "5"
|
||||
pm-version-major: "4"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -71,7 +71,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.27, 8.1.14, 8.2.1]
|
||||
php: [8.0.28, 8.1.16, 8.2.3]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -81,7 +81,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "5"
|
||||
pm-version-major: "4"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -110,7 +110,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.27, 8.1.14, 8.2.1]
|
||||
php: [8.0.28, 8.1.16, 8.2.3]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -122,7 +122,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "5"
|
||||
pm-version-major: "4"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -151,7 +151,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.27, 8.1.14, 8.2.1]
|
||||
php: [8.0.28, 8.1.16, 8.2.3]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -161,7 +161,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "5"
|
||||
pm-version-major: "4"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -185,9 +185,6 @@ jobs:
|
||||
- name: Regenerate KnownTranslation APIs
|
||||
run: php build/generate-known-translation-apis.php
|
||||
|
||||
- name: Regenerate RuntimeEnum(De)serializer
|
||||
run: php build/generate-runtime-enum-serializers.php
|
||||
|
||||
- name: Regenerate BedrockData available files constants
|
||||
run: php build/generate-bedrockdata-path-consts.php
|
||||
|
||||
|
59
.github/workflows/update-updater-api.yml
vendored
59
.github/workflows/update-updater-api.yml
vendored
@ -15,23 +15,68 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
repository: pmmp/update.pmmp.io
|
||||
repository: ${{ github.repository_owner }}/update.pmmp.io
|
||||
ssh-key: ${{ secrets.UPDATE_PMMP_IO_DEPLOY_KEY }}
|
||||
|
||||
- name: Get actual tag name
|
||||
id: tag-name
|
||||
run: echo ::set-output name=TAG_NAME::$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
|
||||
run: echo TAG_NAME=$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download new release information
|
||||
run: curl -f -L ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.tag-name.outputs.TAG_NAME }}/build_info.json -o new_build_info.json
|
||||
|
||||
- name: Detect channel
|
||||
- name: Detect channels
|
||||
id: channel
|
||||
run: echo ::set-output name=CHANNEL::$(jq -r '.channel' new_build_info.json)
|
||||
|
||||
- name: Copy release information
|
||||
run: |
|
||||
cp new_build_info.json channels/${{ steps.channel.outputs.CHANNEL }}.json
|
||||
CHANNEL=$(jq -r '.channel' new_build_info.json)
|
||||
VERSION=${{ steps.tag-name.outputs.TAG_NAME }}
|
||||
echo CHANNEL=$CHANNEL >> $GITHUB_OUTPUT
|
||||
if [ "$CHANNEL" == "stable" ]; then
|
||||
echo MAJOR=$(echo $VERSION | cut -d. -f1) >> $GITHUB_OUTPUT
|
||||
echo MINOR=$(echo $VERSION | cut -d. -f1-2) >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo MAJOR=$(echo $VERSION | cut -d. -f1)-$CHANNEL >> $GITHUB_OUTPUT
|
||||
echo MINOR=$(echo $VERSION | cut -d. -f1-2)-$CHANNEL >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Update channel info
|
||||
run: |
|
||||
function version_id() {
|
||||
major=$(echo $1 | cut -d. -f1)
|
||||
minor=$(echo $1 | cut -d. -f2)
|
||||
patch=$(echo $1 | cut -d. -f3)
|
||||
echo $(((major * 1000000) + (minor * 1000) + patch))
|
||||
}
|
||||
|
||||
function update_channel() {
|
||||
local target_file_name="$1"
|
||||
local new_file_name="$2"
|
||||
|
||||
local old_version_id
|
||||
local new_version_id
|
||||
|
||||
if [ ! -f "$target_file_name" ]; then
|
||||
echo "Creating channel file: $target_file_name"
|
||||
cp "$new_file_name" "$target_file_name"
|
||||
else
|
||||
old_version_id=$(version_id "$(jq -r '.base_version' "$target_file_name")")
|
||||
new_version_id=$(version_id "$(jq -r '.base_version' "$new_file_name")")
|
||||
|
||||
echo "Old version ID: $old_version_id"
|
||||
echo "New version ID: $new_version_id"
|
||||
|
||||
if [ $new_version_id -ge $old_version_id ]; then #suffixed versions will have the same version ID - assume they'll always be newer
|
||||
echo "Updating channel file: $target_file_name ($old_version_id -> $new_version_id)"
|
||||
cp "$new_file_name" "$target_file_name"
|
||||
else
|
||||
echo "Version $new_version_id is less than $old_version_id, not updating channel file: $target_file_name"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
update_channel "channels/${{ steps.channel.outputs.CHANNEL }}.json" "new_build_info.json"
|
||||
update_channel "channels/${{ steps.channel.outputs.MAJOR }}.json" "new_build_info.json"
|
||||
update_channel "channels/${{ steps.channel.outputs.MINOR }}.json" "new_build_info.json"
|
||||
rm new_build_info.json
|
||||
|
||||
- name: Commit changes
|
||||
|
@ -21,7 +21,7 @@ Larger contributions like feature additions should be preceded by a [Change Prop
|
||||
## Choosing a target branch
|
||||
PocketMine-MP has three primary branches of development.
|
||||
|
||||
| Type of change | `stable` | `next-minor` | `next-major` |
|
||||
| Type of change | `stable` | `minor-next` | `major-next` |
|
||||
|:---------------|:--------:|:------------:|:------------:|
|
||||
| Bug fixes | ✔️ | ✔️ | ✔️ |
|
||||
| Improvements to API docs | ✔️ | ✔️ | ✔️ |
|
||||
|
@ -1,197 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_block_serializer_consts;
|
||||
|
||||
use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues;
|
||||
use pocketmine\data\bedrock\block\BlockTypeNames;
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\nbt\NbtException;
|
||||
use pocketmine\network\mcpe\convert\BlockStateDictionary;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Utils;
|
||||
use function array_values;
|
||||
use function asort;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function fclose;
|
||||
use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function is_string;
|
||||
use function ksort;
|
||||
use function mb_strtoupper;
|
||||
use function sort;
|
||||
use function strrpos;
|
||||
use function strtoupper;
|
||||
use function substr;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
class BlockPaletteReport{
|
||||
/**
|
||||
* @var string[]
|
||||
* @phpstan-var array<string, string>
|
||||
*/
|
||||
public array $seenTypes = [];
|
||||
/**
|
||||
* @var string[][]
|
||||
* @phpstan-var array<string, array<mixed, mixed>>
|
||||
*/
|
||||
public array $seenStateValues = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockStateData[] $states
|
||||
* @phpstan-param list<BlockStateData> $states
|
||||
*/
|
||||
function generateBlockPaletteReport(array $states) : BlockPaletteReport{
|
||||
$result = new BlockPaletteReport();
|
||||
|
||||
foreach($states as $stateData){
|
||||
$name = $stateData->getName();
|
||||
$result->seenTypes[$name] = $name;
|
||||
foreach(Utils::stringifyKeys($stateData->getStates()) as $k => $v){
|
||||
$result->seenStateValues[$k][$v->getValue()] = $v->getValue();
|
||||
asort($result->seenStateValues[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
ksort($result->seenTypes, SORT_STRING);
|
||||
ksort($result->seenStateValues, SORT_STRING);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function constifyMcId(string $id) : string{
|
||||
return strtoupper(explode(":", $id, 2)[1]);
|
||||
}
|
||||
|
||||
function generateClassHeader(string $className) : string{
|
||||
$backslashPos = strrpos($className, "\\");
|
||||
if($backslashPos === false){
|
||||
throw new AssumptionFailedError("Expected a namespaced class FQN");
|
||||
}
|
||||
$namespace = substr($className, 0, $backslashPos);
|
||||
$shortName = substr($className, $backslashPos + 1);
|
||||
return <<<HEADER
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace $namespace;
|
||||
|
||||
/**
|
||||
* This class is generated automatically from the block palette for the current version. Do not edit it manually.
|
||||
*/
|
||||
final class $shortName{
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
|
||||
HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param list<string> $seenIds
|
||||
*/
|
||||
function generateBlockIds(array $seenIds) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockTypeNames.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockTypeNames::class));
|
||||
|
||||
foreach($seenIds as $id){
|
||||
fwrite($output, "\tpublic const " . constifyMcId($id) . " = \"" . $id . "\";\n");
|
||||
}
|
||||
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
function generateBlockStateNames(BlockPaletteReport $data) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockStateNames.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockStateNames::class));
|
||||
foreach(Utils::stringifyKeys($data->seenStateValues) as $state => $values){
|
||||
$constName = mb_strtoupper($state, 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$state\";\n");
|
||||
}
|
||||
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
function generateBlockStringValues(BlockPaletteReport $data) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockStateStringValues.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockStateStringValues::class));
|
||||
foreach(Utils::stringifyKeys($data->seenStateValues) as $stateName => $values){
|
||||
$anyWritten = false;
|
||||
sort($values, SORT_STRING);
|
||||
foreach($values as $value){
|
||||
if(!is_string($value)){
|
||||
continue;
|
||||
}
|
||||
$anyWritten = true;
|
||||
$constName = mb_strtoupper($stateName . "_" . $value, 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$value\";\n");
|
||||
}
|
||||
if($anyWritten){
|
||||
fwrite($output, "\n");
|
||||
}
|
||||
}
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "This script regenerates BlockTypeNames, BlockStateNames and BlockStateStringValues from a given palette file\n");
|
||||
fwrite(STDERR, "Required arguments: path to block palette file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$palettePath = $argv[1];
|
||||
$paletteRaw = file_get_contents($palettePath);
|
||||
if($paletteRaw === false){
|
||||
fwrite(STDERR, "Failed to read block palette file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try{
|
||||
$states = BlockStateDictionary::loadPaletteFromString($paletteRaw);
|
||||
}catch(NbtException){
|
||||
fwrite(STDERR, "Invalid block palette file $argv[1]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$report = generateBlockPaletteReport($states);
|
||||
generateBlockIds(array_values($report->seenTypes));
|
||||
generateBlockStateNames($report);
|
||||
generateBlockStringValues($report);
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_item_serializer_ids;
|
||||
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\network\mcpe\convert\ItemTypeDictionaryFromDataHelper;
|
||||
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
|
||||
use pocketmine\utils\Utils;
|
||||
use function asort;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function fclose;
|
||||
use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function strtoupper;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
function constifyMcId(string $id) : string{
|
||||
return strtoupper(explode(":", $id, 2)[1]);
|
||||
}
|
||||
|
||||
function generateItemIds(ItemTypeDictionary $dictionary) : void{
|
||||
$ids = [];
|
||||
foreach($dictionary->getEntries() as $entry){
|
||||
if($entry->getNumericId() < 256){ //blockitems are serialized via BlockStateSerializer
|
||||
continue;
|
||||
}
|
||||
$ids[$entry->getStringId()] = $entry->getStringId();
|
||||
}
|
||||
asort($ids, SORT_STRING);
|
||||
|
||||
$file = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/item/ItemTypeNames.php', 'wb'));
|
||||
|
||||
fwrite($file, <<<'HEADER'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\item;
|
||||
|
||||
/**
|
||||
* This class is generated automatically from the item type dictionary for the current version. Do not edit it manually.
|
||||
*/
|
||||
final class ItemTypeNames{
|
||||
|
||||
HEADER
|
||||
);
|
||||
|
||||
foreach(Utils::stringifyKeys($ids) as $id){
|
||||
fwrite($file, "\tpublic const " . constifyMcId($id) . " = \"" . $id . "\";\n");
|
||||
}
|
||||
fwrite($file, "}\n");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "This script regenerates ItemTypeNames from a given item dictionary file\n");
|
||||
fwrite(STDERR, "Required argument: path to item type dictionary file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$raw = file_get_contents($argv[1]);
|
||||
if($raw === false){
|
||||
fwrite(STDERR, "Failed to read item type dictionary file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$dictionary = ItemTypeDictionaryFromDataHelper::loadFromString($raw);
|
||||
generateItemIds($dictionary);
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
@ -1,263 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_runtime_enum_serializers;
|
||||
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\block\utils\LeverFacing;
|
||||
use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\item\MedicineType;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SuspiciousStewType;
|
||||
use function array_key_first;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function implode;
|
||||
use function ksort;
|
||||
use function lcfirst;
|
||||
use function log;
|
||||
use function ob_get_clean;
|
||||
use function ob_start;
|
||||
use const SORT_STRING;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildWriterFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->writeInt($bits, match(\$value){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$memberName => $key,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new \pocketmine\utils\AssumptionFailedError(\"All $virtualTypeName cases should be covered\")";
|
||||
$lines[] = "\t});";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildReaderFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$value = match(\$this->readInt($bits)){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$key => $memberName,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new InvalidSerializedRuntimeDataException(\"Invalid serialized value for $virtualTypeName\")";
|
||||
$lines[] = "\t};";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
function buildInterfaceFunc(string $nativeTypeName, string $functionName) : string{
|
||||
return "public function $functionName(\\$nativeTypeName &\$value) : void;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildSizeCalculationFunc(string $nativeTypeName, string $functionName, array $memberNames) : array{
|
||||
$lines = [];
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->addBits(" . getBitsRequired($memberNames) . ");";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $members
|
||||
*/
|
||||
function getBitsRequired(array $members) : int{
|
||||
return (int) ceil(log(count($members), 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object[] $members
|
||||
* @phpstan-param array<string, object> $members
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function stringifyEnumMembers(array $members, string $enumClass) : array{
|
||||
ksort($members, SORT_STRING);
|
||||
return array_map(fn(string $enumCaseName) => "\\$enumClass::$enumCaseName()", array_keys($members));
|
||||
}
|
||||
|
||||
$enumsUsed = [
|
||||
BellAttachmentType::getAll(),
|
||||
CopperOxidation::getAll(),
|
||||
CoralType::getAll(),
|
||||
DirtType::getAll(),
|
||||
DyeColor::getAll(),
|
||||
FroglightType::getAll(),
|
||||
LeverFacing::getAll(),
|
||||
MedicineType::getAll(),
|
||||
MushroomBlockType::getAll(),
|
||||
SkullType::getAll(),
|
||||
SlabType::getAll(),
|
||||
SuspiciousStewType::getAll(),
|
||||
PotionType::getAll()
|
||||
];
|
||||
|
||||
$readerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function readInt(int \$bits) : int;"
|
||||
]
|
||||
];
|
||||
$writerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function writeInt(int \$bits, int \$value) : void;"
|
||||
]
|
||||
];
|
||||
$interfaceFuncs = [];
|
||||
$sizeCalculationFuncs = [
|
||||
"" => [
|
||||
"abstract protected function addBits(int \$bits) : void;"
|
||||
]
|
||||
];
|
||||
|
||||
foreach($enumsUsed as $enumMembers){
|
||||
if(count($enumMembers) === 0){
|
||||
throw new \InvalidArgumentException("Enum members cannot be empty");
|
||||
}
|
||||
$reflect = new \ReflectionClass($enumMembers[array_key_first($enumMembers)]);
|
||||
$virtualTypeName = $reflect->getShortName();
|
||||
$nativeTypeName = $reflect->getName();
|
||||
$functionName = lcfirst($virtualTypeName);
|
||||
|
||||
$stringifiedMembers = stringifyEnumMembers($enumMembers, $nativeTypeName);
|
||||
$writerFuncs[$functionName] = buildWriterFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$readerFuncs[$functionName] = buildReaderFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$interfaceFuncs[$functionName] = [buildInterfaceFunc(
|
||||
$nativeTypeName,
|
||||
$functionName
|
||||
)];
|
||||
$sizeCalculationFuncs[$functionName] = buildSizeCalculationFunc(
|
||||
$nativeTypeName,
|
||||
$functionName,
|
||||
$stringifiedMembers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[][] $functions
|
||||
* @phpstan-param array<string, list<string>> $functions
|
||||
*/
|
||||
function printFunctions(array $functions, string $className, string $classType) : void{
|
||||
ksort($functions, SORT_STRING);
|
||||
|
||||
ob_start();
|
||||
|
||||
echo <<<'HEADER'
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
*/
|
||||
|
||||
HEADER;
|
||||
|
||||
echo "$classType $className{\n\n";
|
||||
echo implode("\n\n", array_map(fn(array $functionLines) => "\t" . implode("\n\t", $functionLines), $functions));
|
||||
echo "\n\n}\n";
|
||||
|
||||
file_put_contents(dirname(__DIR__) . '/src/data/runtime/' . $className . '.php', ob_get_clean());
|
||||
}
|
||||
|
||||
printFunctions($writerFuncs, "RuntimeEnumSerializerTrait", "trait");
|
||||
printFunctions($readerFuncs, "RuntimeEnumDeserializerTrait", "trait");
|
||||
printFunctions($interfaceFuncs, "RuntimeEnumDescriber", "interface");
|
||||
printFunctions($sizeCalculationFuncs, "RuntimeEnumSizeCalculatorTrait", "trait");
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
@ -38,7 +38,6 @@ use function is_string;
|
||||
use function max;
|
||||
use function preg_match;
|
||||
use function preg_replace;
|
||||
use function sleep;
|
||||
use function sprintf;
|
||||
use function str_pad;
|
||||
use function strlen;
|
||||
@ -160,9 +159,6 @@ function main() : void{
|
||||
replaceVersion($versionInfoPath, $nextVer->getBaseVersion(), true, $channel);
|
||||
systemWrapper('git add "' . $versionInfoPath . '"', "failed to stage changes for post-release commit");
|
||||
systemWrapper('git commit -m "' . $nextVer->getBaseVersion() . ' is next" --include "' . $versionInfoPath . '"', "failed to create post-release commit");
|
||||
echo "pushing changes in 5 seconds\n";
|
||||
sleep(5);
|
||||
systemWrapper('git push origin HEAD ' . $currentVer->getBaseVersion(), "failed to push changes to remote");
|
||||
}
|
||||
|
||||
main();
|
||||
|
Submodule build/php updated: b2207cf70d...a464454d1e
14
changelogs/4.17.md
Normal file
14
changelogs/4.17.md
Normal file
@ -0,0 +1,14 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.70**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.17.0
|
||||
Released 14th March 2023.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.70.
|
||||
- Removed support for older versions.
|
45
changelogs/4.18-alpha.md
Normal file
45
changelogs/4.18-alpha.md
Normal file
@ -0,0 +1,45 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.70**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the `pocketmine\network\mcpe` namespace are compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the `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.
|
||||
|
||||
### Alpha release warning
|
||||
Alpha releases are **experimental**. Features introduced in these releases are subject to change or removal.
|
||||
|
||||
APIs which existed **prior** to this version will continue to work as normal, so plugins which use them will continue to work.
|
||||
|
||||
### Highlights
|
||||
This version makes changes to the internal network system to improve server performance and reduce memory usage.
|
||||
|
||||
While these changes don't affect non-internal API, they are still significant enough to warrant a new minor version, as they may break plugins which use the internal network API (not recommended).
|
||||
|
||||
# 4.18.0-ALPHA1
|
||||
Released 16th March 2023.
|
||||
|
||||
## General
|
||||
- Improved server performance in congested areas of the world (lots of players and/or entities in the same area).
|
||||
|
||||
## API
|
||||
### `pocketmine\event\server`
|
||||
- The following new classes have been added:
|
||||
- `DataPacketDecodeEvent` - called before a packet is decoded by a `NetworkSession`; useful to mitigate DoS attacks if PocketMine-MP hasn't been patched against new bugs yet
|
||||
|
||||
## Internals
|
||||
- Introduced new system for broadcasting entity events to network sessions.
|
||||
- This change improves performance when lots of players and/or entities are in the same area.
|
||||
- New interface `EntityEventBroadcaster` and class `StandardEntityEventBroadcaster` have been added to implement this.
|
||||
- All entity-specific `on*()` and `sync*()` methods have been removed from `NetworkSession` (BC break).
|
||||
- `NetworkSession` now accepts an `EntityEventBroadcaster` instance in its constructor.
|
||||
- `NetworkBroadcastUtils::broadcastEntityEvent()` can be used to efficiently broadcast events to unique broadcasters shared by several network sessions.
|
||||
- All network sessions now share the same `PacketSerializerContext` and `PacketBroadcaster` by default.
|
||||
- Previously, every session had its own context, meaning that broadcast optimisations were not used, causing significant performance losses compared to 3.x.
|
||||
- This change improves performance in congested areas by allowing reuse of previously encoded packet buffers for all sessions sharing the same context.
|
||||
- Packet broadcasts are automatically encoded separately per unique `PacketSerializerContext` instance. This allows, for example, a multi-version fork to have a separate context for each protocol version, to ensure maximum broadcast efficiency while encoding different packets for different versions.
|
||||
- `PacketSerializerContext` is now passed in `NetworkSession::__construct()`, instead of being created by the session.
|
||||
- `StandardPacketBroadcaster` is now locked to a single `PacketSerializer` context, reducing complexity.
|
||||
- Introduced `NetworkBroadcastUtils::broadcastPackets()`, replacing `Server->broadcastPackets()`.
|
||||
- `Server->broadcastPackets()` has been deprecated. It will be removed in a future version.
|
File diff suppressed because it is too large
Load Diff
@ -1,44 +0,0 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.62**
|
||||
|
||||
5.0.0 is a major update to PocketMine-MP, including many new features and API changes. It is **not** compatible with plugins written for previous versions of PocketMine-MP.
|
||||
|
||||
**During the beta phase, no new features will be added.**
|
||||
|
||||
This stage of development is focused on stability and cleaning up any major issues introduced during the alpha stage.
|
||||
|
||||
## WARNING
|
||||
**This is a BETA release.** This means that it may be unstable, and is not yet ready for production use.
|
||||
|
||||
Since this version has undergone substantial changes compared to 4.x, plugins written for 4.x will need to be updated to work on this version.
|
||||
|
||||
Breaking API changes may still occur during the beta phase, but only if they are strictly necessary to fix a problem prior to full release.
|
||||
|
||||
**BACK UP your data before testing this.** This version will work with worlds and player data from 4.x,
|
||||
BUT any world or player data loaded in 5.0.0 will not work in 4.x due to backwards-incompatible storage format changes.
|
||||
|
||||
# 5.0.0-BETA1
|
||||
Released 7th March 2023.
|
||||
|
||||
**This release includes changes from the following releases:**
|
||||
- [All 5.0.0 alpha releases](https://github.com/pmmp/PocketMine-MP/blob/5.0.0-BETA1/changelogs/5.0-alpha.md)
|
||||
- [4.15.2](https://github.com/pmmp/PocketMine-MP/blob/5.0.0-BETA1/changelogs/4.15.md#4152)
|
||||
- [4.15.3](https://github.com/pmmp/PocketMine-MP/blob/5.0.0-BETA1/changelogs/4.15.md#4153)
|
||||
- [4.16.0](https://github.com/pmmp/PocketMine-MP/blob/5.0.0-BETA1/changelogs/4.16.md#4160)
|
||||
|
||||
## API
|
||||
### `pocketmine\block`
|
||||
- Improved documentation for the following methods:
|
||||
- `Block->getTypeId()`
|
||||
- `Block->getStateId()`
|
||||
- `Block->describeType()`
|
||||
- `Block->describeState()`
|
||||
|
||||
### `pocketmine\command`
|
||||
- The following API methods have been renamed:
|
||||
- `Command->getPermission()` -> `Command->getPermissions()`
|
||||
|
||||
## Internals
|
||||
- The following methods have been renamed:
|
||||
- `Block->computeStateData()` -> `Block->computeTypeAndStateData()`
|
||||
- `Block->decodeStateData()` -> `Block->decodeTypeAndStateData()`
|
||||
- Wall state data now packs connections into 7 bits instead of 8.
|
@ -22,7 +22,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-pthreads": "^4.0",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
@ -34,28 +34,29 @@
|
||||
"adhocore/json-comment": "^1.1",
|
||||
"fgrosse/phpasn1": "^2.3",
|
||||
"netresearch/jsonmapper": "^4.0",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "^1.0.0",
|
||||
"pocketmine/bedrock-data": "~2.0.0+bedrock-1.19.60",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "^1.0.0",
|
||||
"pocketmine/bedrock-protocol": "~19.3.0+bedrock-1.19.62",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "~1.1.1+bedrock-1.19.70",
|
||||
"pocketmine/bedrock-data": "~2.1.1+bedrock-1.19.70",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "~1.1.0+bedrock-1.19.70",
|
||||
"pocketmine/bedrock-protocol": "~20.0.0+bedrock-1.19.70",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.3.0",
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.19.0",
|
||||
"pocketmine/locale-data": "~2.18.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.5.0",
|
||||
"pocketmine/log-pthreads": "^0.4.0",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
"pocketmine/nbt": "^0.3.2",
|
||||
"pocketmine/raklib": "^0.15.0",
|
||||
"pocketmine/raklib-ipc": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.4.0",
|
||||
"pocketmine/raklib": "^0.14.2",
|
||||
"pocketmine/raklib-ipc": "^0.1.0",
|
||||
"pocketmine/snooze": "^0.3.0",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"symfony/filesystem": "^5.4"
|
||||
"symfony/filesystem": "^5.4",
|
||||
"webmozart/path-util": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.10.4",
|
||||
"phpstan/phpstan": "1.10.6",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
|
305
composer.lock
generated
305
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": "9751c90077792bd5d12ebb53a0214ec1",
|
||||
"content-hash": "1d0c1d2fe668d85ae87110a1e3cfac05",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -250,16 +250,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-block-upgrade-schema",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git",
|
||||
"reference": "78c965a2316986ac0eaf3235d75efb187127e7a2"
|
||||
"reference": "e0540343e649a92126a1d4071ec401a811416c76"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/78c965a2316986ac0eaf3235d75efb187127e7a2",
|
||||
"reference": "78c965a2316986ac0eaf3235d75efb187127e7a2",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/e0540343e649a92126a1d4071ec401a811416c76",
|
||||
"reference": "e0540343e649a92126a1d4071ec401a811416c76",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -270,22 +270,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/1.1.0"
|
||||
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/1.1.1"
|
||||
},
|
||||
"time": "2023-03-06T17:53:36+00:00"
|
||||
"time": "2023-03-08T23:45:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-data",
|
||||
"version": "2.0.0+bedrock-1.19.60",
|
||||
"version": "2.1.1+bedrock-1.19.70",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "957e49b2381641af29f595e4f32ded3e76ce4723"
|
||||
"reference": "cba0567bcb25f987f2712092f8d662056719e82d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/957e49b2381641af29f595e4f32ded3e76ce4723",
|
||||
"reference": "957e49b2381641af29f595e4f32ded3e76ce4723",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/cba0567bcb25f987f2712092f8d662056719e82d",
|
||||
"reference": "cba0567bcb25f987f2712092f8d662056719e82d",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -296,22 +296,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/2.0.0+bedrock-1.19.60"
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/2.1.1+bedrock-1.19.70"
|
||||
},
|
||||
"time": "2023-02-23T21:25:04+00:00"
|
||||
"time": "2023-03-14T18:03:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-item-upgrade-schema",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git",
|
||||
"reference": "7e53f77ea34ba30b1f94d3c24e64e19d3c4296e7"
|
||||
"reference": "aab89a1f121a0c127557a4a0cf981330301c9c45"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/7e53f77ea34ba30b1f94d3c24e64e19d3c4296e7",
|
||||
"reference": "7e53f77ea34ba30b1f94d3c24e64e19d3c4296e7",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/aab89a1f121a0c127557a4a0cf981330301c9c45",
|
||||
"reference": "aab89a1f121a0c127557a4a0cf981330301c9c45",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -322,22 +322,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.0.0"
|
||||
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.1.0"
|
||||
},
|
||||
"time": "2023-02-01T22:50:02+00:00"
|
||||
"time": "2023-03-08T22:27:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-protocol",
|
||||
"version": "19.3.0+bedrock-1.19.62",
|
||||
"version": "20.0.0+bedrock-1.19.70",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockProtocol.git",
|
||||
"reference": "a5bf4753c7f30f781c4541918e238f5bb637e7ad"
|
||||
"reference": "4892a5020187da805d7b46ab522d8185b0283726"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/a5bf4753c7f30f781c4541918e238f5bb637e7ad",
|
||||
"reference": "a5bf4753c7f30f781c4541918e238f5bb637e7ad",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/4892a5020187da805d7b46ab522d8185b0283726",
|
||||
"reference": "4892a5020187da805d7b46ab522d8185b0283726",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -351,7 +351,7 @@
|
||||
"ramsey/uuid": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.13",
|
||||
"phpstan/phpstan": "1.10.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
@ -369,9 +369,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/19.3.0+bedrock-1.19.62"
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/20.0.0+bedrock-1.19.70"
|
||||
},
|
||||
"time": "2023-02-19T16:11:03+00:00"
|
||||
"time": "2023-03-14T17:06:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
@ -467,20 +467,20 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/classloader",
|
||||
"version": "0.3.0",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/ClassLoader.git",
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026"
|
||||
"reference": "49ea303993efdfb39cd302e2156d50aa78209e78"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/407caf521186ec1f03024f39031cc681ad491026",
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/49ea303993efdfb39cd302e2156d50aa78209e78",
|
||||
"reference": "49ea303993efdfb39cd302e2156d50aa78209e78",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"ext-reflection": "*",
|
||||
"php": "^8.0"
|
||||
},
|
||||
@ -489,8 +489,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.9.4",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
@ -506,9 +506,9 @@
|
||||
"description": "Ad-hoc autoloading components used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/ClassLoader/issues",
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/0.3.0"
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/0.2.0"
|
||||
},
|
||||
"time": "2023-01-23T19:46:53+00:00"
|
||||
"time": "2021-11-01T20:17:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/color",
|
||||
@ -589,16 +589,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/locale-data",
|
||||
"version": "2.19.0",
|
||||
"version": "2.18.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Language.git",
|
||||
"reference": "f47d1687f21f09d2858f040873184a11746b1cf7"
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/f47d1687f21f09d2858f040873184a11746b1cf7",
|
||||
"reference": "f47d1687f21f09d2858f040873184a11746b1cf7",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -606,9 +606,9 @@
|
||||
"description": "Language resources used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Language/issues",
|
||||
"source": "https://github.com/pmmp/Language/tree/2.19.0"
|
||||
"source": "https://github.com/pmmp/Language/tree/2.18.3"
|
||||
},
|
||||
"time": "2023-02-13T13:55:22+00:00"
|
||||
"time": "2023-01-17T21:43:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log",
|
||||
@ -653,21 +653,21 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log-pthreads",
|
||||
"version": "0.5.0",
|
||||
"version": "0.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/LogPthreads.git",
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666"
|
||||
"reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/61f709e8cf36bcc24e4efe02acded680a1ce23cd",
|
||||
"reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"php": "^8.0",
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"pocketmine/log": "^0.4.0"
|
||||
},
|
||||
"conflict": {
|
||||
@ -675,8 +675,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.8.11",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
"phpstan/phpstan": "0.12.88",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -691,9 +691,9 @@
|
||||
"description": "Logging components specialized for pthreads used by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/LogPthreads/issues",
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/0.5.0"
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/0.4.0"
|
||||
},
|
||||
"time": "2023-01-23T19:52:12+00:00"
|
||||
"time": "2021-11-01T21:42:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
@ -780,16 +780,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "0.15.1",
|
||||
"version": "0.14.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "79b7b4d1d7516dc6e322514453645ad9452b20ca"
|
||||
"reference": "aeca667d5ecc4cc18fded612f29e3511bbf62f42"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/79b7b4d1d7516dc6e322514453645ad9452b20ca",
|
||||
"reference": "79b7b4d1d7516dc6e322514453645ad9452b20ca",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/aeca667d5ecc4cc18fded612f29e3511bbf62f42",
|
||||
"reference": "aeca667d5ecc4cc18fded612f29e3511bbf62f42",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -817,33 +817,33 @@
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/RakLib/issues",
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.15.1"
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.14.6"
|
||||
},
|
||||
"time": "2023-03-07T15:10:34+00:00"
|
||||
"time": "2023-03-07T15:10:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib-ipc",
|
||||
"version": "0.2.0",
|
||||
"version": "0.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLibIpc.git",
|
||||
"reference": "26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c"
|
||||
"reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c",
|
||||
"reference": "26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/922a6444b0c6c7daaa5aa5a832107e1ec4738aed",
|
||||
"reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"php-64bit": "*",
|
||||
"pocketmine/binaryutils": "^0.2.0",
|
||||
"pocketmine/raklib": "^0.15.0"
|
||||
"pocketmine/raklib": "^0.13.1 || ^0.14.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.17",
|
||||
"phpstan/phpstan-strict-rules": "^1.0.0"
|
||||
"phpstan/phpstan": "0.12.81",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -858,32 +858,32 @@
|
||||
"description": "Channel-based protocols for inter-thread/inter-process communication with RakLib",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/RakLibIpc/issues",
|
||||
"source": "https://github.com/pmmp/RakLibIpc/tree/0.2.0"
|
||||
"source": "https://github.com/pmmp/RakLibIpc/tree/0.1.1"
|
||||
},
|
||||
"time": "2023-02-13T13:40:40+00:00"
|
||||
"time": "2021-09-22T17:01:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/snooze",
|
||||
"version": "0.4.0",
|
||||
"version": "0.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Snooze.git",
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292"
|
||||
"reference": "0ac8fc2a781c419a1f64ebca4d5835028f59e29b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/0ac8fc2a781c419a1f64ebca4d5835028f59e29b",
|
||||
"reference": "0ac8fc2a781c419a1f64ebca4d5835028f59e29b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "^5.0",
|
||||
"php-64bit": "^8.0"
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"php-64bit": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "1.9.14",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -898,9 +898,9 @@
|
||||
"description": "Thread notification management library for code using the pthreads extension",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Snooze/issues",
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.4.0"
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.3.1"
|
||||
},
|
||||
"time": "2023-01-23T19:43:19+00:00"
|
||||
"time": "2021-11-01T20:50:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
@ -1474,6 +1474,115 @@
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
"vimeo/psalm": "<4.6.1 || 4.6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.10-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||
},
|
||||
"time": "2022-06-03T18:03:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/path-util",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/path-util.git",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"webmozart/assert": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"sebastian/version": "^1.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\PathUtil\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozart/path-util/issues",
|
||||
"source": "https://github.com/webmozart/path-util/tree/2.3.0"
|
||||
},
|
||||
"abandoned": "symfony/filesystem",
|
||||
"time": "2015-12-17T08:42:14+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -1549,16 +1658,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.11.0",
|
||||
"version": "1.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
|
||||
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1596,7 +1705,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1604,7 +1713,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-03T13:19:32+00:00"
|
||||
"time": "2023-03-08T13:26:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
@ -1775,16 +1884,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.4",
|
||||
"version": "1.10.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "8d39218664b45a4a42d5be66d2b63dcf8c149982"
|
||||
"reference": "50d089a3e0904b0fe7e2cf2d4fd37d427d64235a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/8d39218664b45a4a42d5be66d2b63dcf8c149982",
|
||||
"reference": "8d39218664b45a4a42d5be66d2b63dcf8c149982",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/50d089a3e0904b0fe7e2cf2d4fd37d427d64235a",
|
||||
"reference": "50d089a3e0904b0fe7e2cf2d4fd37d427d64235a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1814,7 +1923,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.10.4"
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.10.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1830,7 +1939,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-06T13:39:20+00:00"
|
||||
"time": "2023-03-09T16:55:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan-phpunit",
|
||||
@ -2253,16 +2362,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.6.4",
|
||||
"version": "9.6.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d"
|
||||
"reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9125ee085b6d95e78277dc07aa1f46f9e0607b8d",
|
||||
"reference": "9125ee085b6d95e78277dc07aa1f46f9e0607b8d",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86e761949019ae83f49240b2f2123fb5ab3b2fc5",
|
||||
"reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2295,8 +2404,8 @@
|
||||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*",
|
||||
"ext-xdebug": "*"
|
||||
"ext-soap": "To be able to generate mocks based on WSDL files",
|
||||
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
|
||||
},
|
||||
"bin": [
|
||||
"phpunit"
|
||||
@ -2335,7 +2444,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.4"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2351,7 +2460,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-27T13:06:37+00:00"
|
||||
"time": "2023-03-09T06:34:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@ -3391,7 +3500,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-pthreads": "^4.0",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
|
@ -1,6 +1,7 @@
|
||||
includes:
|
||||
- tests/phpstan/analyse-for-current-php-version.neon.php
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/gc-hacks.neon
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
- tests/phpstan/configs/php-bugs.neon
|
||||
- tests/phpstan/configs/phpstan-bugs.neon
|
||||
|
File diff suppressed because it is too large
Load Diff
4898
resources/legacy_creativeitems.json
Normal file
4898
resources/legacy_creativeitems.json
Normal file
File diff suppressed because it is too large
Load Diff
49988
resources/legacy_recipes.json
Normal file
49988
resources/legacy_recipes.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -282,8 +282,10 @@ class MemoryManager{
|
||||
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
*/
|
||||
public static function dumpMemory(mixed $startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
$hardLimit = Utils::assumeNotFalse(ini_get('memory_limit'), "memory_limit INI directive should always exist");
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
@ -474,6 +476,7 @@ class MemoryManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param object[] $objects reference parameter
|
||||
* @param int[] $refCounts reference parameter
|
||||
*
|
||||
@ -481,8 +484,10 @@ class MemoryManager{
|
||||
* @phpstan-param array<string, int> $refCounts
|
||||
* @phpstan-param-out array<string, object> $objects
|
||||
* @phpstan-param-out array<string, int> $refCounts
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function continueDump(mixed $from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : mixed{
|
||||
private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
if($maxNesting <= 0){
|
||||
return "(error) NESTING LIMIT REACHED";
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ namespace pocketmine {
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "5.1.0") < 0 || version_compare($pthreads_version, "6.0.0") >= 0){
|
||||
$messages[] = "pthreads ^5.0.0 is required, while you have $pthreads_version.";
|
||||
if(version_compare($pthreads_version, "4.0.0") < 0 || version_compare($pthreads_version, "5.0.0") >= 0){
|
||||
$messages[] = "pthreads ^4.0.0 is required, while you have $pthreads_version.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@ use pocketmine\event\player\PlayerCreationEvent;
|
||||
use pocketmine\event\player\PlayerDataSaveEvent;
|
||||
use pocketmine\event\player\PlayerLoginEvent;
|
||||
use pocketmine\event\server\CommandEvent;
|
||||
use pocketmine\event\server\DataPacketSendEvent;
|
||||
use pocketmine\event\server\QueryRegenerateEvent;
|
||||
use pocketmine\lang\KnownTranslationFactory;
|
||||
use pocketmine\lang\Language;
|
||||
@ -54,13 +53,19 @@ use pocketmine\network\mcpe\compression\CompressBatchPromise;
|
||||
use pocketmine\network\mcpe\compression\CompressBatchTask;
|
||||
use pocketmine\network\mcpe\compression\Compressor;
|
||||
use pocketmine\network\mcpe\compression\ZlibCompressor;
|
||||
use pocketmine\network\mcpe\convert\GlobalItemTypeDictionary;
|
||||
use pocketmine\network\mcpe\encryption\EncryptionContext;
|
||||
use pocketmine\network\mcpe\EntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\NetworkBroadcastUtils;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\PacketBroadcaster;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketBatch;
|
||||
use pocketmine\network\mcpe\protocol\serializer\PacketSerializerContext;
|
||||
use pocketmine\network\mcpe\raklib\RakLibInterface;
|
||||
use pocketmine\network\mcpe\StandardEntityEventBroadcaster;
|
||||
use pocketmine\network\mcpe\StandardPacketBroadcaster;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\network\NetworkInterfaceStartException;
|
||||
use pocketmine\network\query\DedicatedQueryNetworkInterface;
|
||||
@ -491,7 +496,10 @@ class Server{
|
||||
return $this->configGroup->getPropertyBool("player.save-player-data", true);
|
||||
}
|
||||
|
||||
public function getOfflinePlayer(string $name) : Player|OfflinePlayer|null{
|
||||
/**
|
||||
* @return OfflinePlayer|Player
|
||||
*/
|
||||
public function getOfflinePlayer(string $name){
|
||||
$name = strtolower($name);
|
||||
$result = $this->getPlayerExact($name);
|
||||
|
||||
@ -580,7 +588,8 @@ class Server{
|
||||
},
|
||||
function() use ($playerPromiseResolver, $session) : void{
|
||||
if($session->isConnected()){
|
||||
$session->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_respawn());
|
||||
//TODO: this needs to be localized - this might be reached if the spawn world was unloaded while the player was logging in
|
||||
$session->disconnect("Failed to find a safe spawn location");
|
||||
}
|
||||
$playerPromiseResolver->reject();
|
||||
}
|
||||
@ -958,7 +967,7 @@ class Server{
|
||||
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
|
||||
$this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\BEDROCK_DATA_PATH, "recipes"));
|
||||
$this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\RESOURCE_PATH, "legacy_recipes.json"));
|
||||
|
||||
$this->resourceManager = new ResourcePackManager(Path::join($this->getDataPath(), "resource_packs"), $this->logger);
|
||||
|
||||
@ -1165,10 +1174,18 @@ class Server{
|
||||
return !$anyWorldFailedToLoad;
|
||||
}
|
||||
|
||||
private function startupPrepareConnectableNetworkInterfaces(string $ip, int $port, bool $ipV6, bool $useQuery) : bool{
|
||||
private function startupPrepareConnectableNetworkInterfaces(
|
||||
string $ip,
|
||||
int $port,
|
||||
bool $ipV6,
|
||||
bool $useQuery,
|
||||
PacketBroadcaster $packetBroadcaster,
|
||||
EntityEventBroadcaster $entityEventBroadcaster,
|
||||
PacketSerializerContext $packetSerializerContext
|
||||
) : bool{
|
||||
$prettyIp = $ipV6 ? "[$ip]" : $ip;
|
||||
try{
|
||||
$rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6));
|
||||
$rakLibRegistered = $this->network->registerInterface(new RakLibInterface($this, $ip, $port, $ipV6, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext));
|
||||
}catch(NetworkInterfaceStartException $e){
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_networkStartFailed(
|
||||
$ip,
|
||||
@ -1194,11 +1211,15 @@ class Server{
|
||||
private function startupPrepareNetworkInterfaces() : bool{
|
||||
$useQuery = $this->configGroup->getConfigBool("enable-query", true);
|
||||
|
||||
$packetSerializerContext = new PacketSerializerContext(GlobalItemTypeDictionary::getInstance()->getDictionary());
|
||||
$packetBroadcaster = new StandardPacketBroadcaster($this, $packetSerializerContext);
|
||||
$entityEventBroadcaster = new StandardEntityEventBroadcaster($packetBroadcaster);
|
||||
|
||||
if(
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery) ||
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIp(), $this->getPort(), false, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext) ||
|
||||
(
|
||||
$this->configGroup->getConfigBool("enable-ipv6", true) &&
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery)
|
||||
!$this->startupPrepareConnectableNetworkInterfaces($this->getIpV6(), $this->getPortV6(), true, $useQuery, $packetBroadcaster, $entityEventBroadcaster, $packetSerializerContext)
|
||||
)
|
||||
){
|
||||
return false;
|
||||
@ -1330,47 +1351,10 @@ class Server{
|
||||
/**
|
||||
* @param Player[] $players
|
||||
* @param ClientboundPacket[] $packets
|
||||
* @deprecated
|
||||
*/
|
||||
public function broadcastPackets(array $players, array $packets) : bool{
|
||||
if(count($packets) === 0){
|
||||
throw new \InvalidArgumentException("Cannot broadcast empty list of packets");
|
||||
}
|
||||
|
||||
return Timings::$broadcastPackets->time(function() use ($players, $packets) : bool{
|
||||
/** @var NetworkSession[] $recipients */
|
||||
$recipients = [];
|
||||
foreach($players as $player){
|
||||
if($player->isConnected()){
|
||||
$recipients[] = $player->getNetworkSession();
|
||||
}
|
||||
}
|
||||
if(count($recipients) === 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
$ev = new DataPacketSendEvent($recipients, $packets);
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
$recipients = $ev->getTargets();
|
||||
$packets = $ev->getPackets();
|
||||
|
||||
/** @var PacketBroadcaster[] $broadcasters */
|
||||
$broadcasters = [];
|
||||
/** @var NetworkSession[][] $broadcasterTargets */
|
||||
$broadcasterTargets = [];
|
||||
foreach($recipients as $recipient){
|
||||
$broadcaster = $recipient->getBroadcaster();
|
||||
$broadcasters[spl_object_id($broadcaster)] = $broadcaster;
|
||||
$broadcasterTargets[spl_object_id($broadcaster)][] = $recipient;
|
||||
}
|
||||
foreach($broadcasters as $broadcaster){
|
||||
$broadcaster->broadcastPackets($broadcasterTargets[spl_object_id($broadcaster)], $packets);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
return NetworkBroadcastUtils::broadcastPackets($players, $packets);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1531,7 +1515,7 @@ class Server{
|
||||
* @param mixed[][]|null $trace
|
||||
* @phpstan-param list<array<string, mixed>>|null $trace
|
||||
*/
|
||||
public function exceptionHandler(\Throwable $e, ?array $trace = null) : void{
|
||||
public function exceptionHandler(\Throwable $e, $trace = null) : void{
|
||||
while(@ob_end_flush()){}
|
||||
global $lastError;
|
||||
|
||||
|
@ -43,7 +43,12 @@ final class ServerConfigGroup{
|
||||
private Config $serverProperties
|
||||
){}
|
||||
|
||||
public function getProperty(string $variable, mixed $defaultValue = null) : mixed{
|
||||
/**
|
||||
* @param mixed $defaultValue
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty(string $variable, $defaultValue = null){
|
||||
if(!array_key_exists($variable, $this->propertyCache)){
|
||||
$v = getopt("", ["$variable::"]);
|
||||
if(isset($v[$variable])){
|
||||
|
@ -31,9 +31,9 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "5.0.0-BETA1";
|
||||
public const BASE_VERSION = "4.18.0-ALPHA1";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "beta";
|
||||
public const BUILD_CHANNEL = "alpha";
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
|
@ -24,22 +24,17 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\AnvilInventory;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\block\utils\FallableTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\AnvilFallSound;
|
||||
use pocketmine\world\sound\Sound;
|
||||
use function lcg_value;
|
||||
use function round;
|
||||
|
||||
class Anvil extends Transparent implements Fallable{
|
||||
use FallableTrait;
|
||||
@ -51,12 +46,21 @@ class Anvil extends Transparent implements Fallable{
|
||||
|
||||
private int $damage = self::UNDAMAGED;
|
||||
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(2, self::UNDAMAGED, self::VERY_DAMAGED, $this->damage);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->damage << 2);
|
||||
}
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3);
|
||||
$this->damage = BlockDataSerializer::readBoundedInt("damage", $stateMeta >> 2, self::UNDAMAGED, self::VERY_DAMAGED);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->damage << 2;
|
||||
}
|
||||
|
||||
public function getDamage() : int{ return $this->damage; }
|
||||
@ -81,7 +85,7 @@ class Anvil extends Transparent implements Fallable{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCurrentWindow(new AnvilInventory($this->position));
|
||||
}
|
||||
@ -96,18 +100,7 @@ class Anvil extends Transparent implements Fallable{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onHitGround(FallingBlock $blockEntity) : bool{
|
||||
if(lcg_value() < 0.05 + (round($blockEntity->getFallDistance()) - 1) * 0.05){
|
||||
if($this->damage !== self::VERY_DAMAGED){
|
||||
$this->damage = $this->damage + 1;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLandSound() : ?Sound{
|
||||
return new AnvilFallSound();
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -23,13 +23,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Bamboo as ItemBamboo;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -55,10 +54,18 @@ class Bamboo extends Transparent{
|
||||
protected bool $ready = false;
|
||||
protected int $leafSize = self::NO_LEAVES;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(2, self::NO_LEAVES, self::LARGE_LEAVES, $this->leafSize);
|
||||
$w->bool($this->thick);
|
||||
$w->bool($this->ready);
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->thick = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_THICK) !== 0;
|
||||
$this->leafSize = BlockDataSerializer::readBoundedInt("leafSize", ($stateMeta >> BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) & BlockLegacyMetadata::BAMBOO_LEAF_SIZE_MASK, self::NO_LEAVES, self::LARGE_LEAVES);
|
||||
$this->ready = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_READY) !== 0;
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
return ($this->thick ? BlockLegacyMetadata::BAMBOO_FLAG_THICK : 0) | ($this->leafSize << BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) | ($this->ready ? BlockLegacyMetadata::BAMBOO_FLAG_READY : 0);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function isThick() : bool{ return $this->thick; }
|
||||
@ -121,11 +128,14 @@ class Bamboo extends Transparent{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block->getTypeId() === BlockTypeIds::GRAVEL ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
$block->hasTypeTag(BlockTypeTags::SAND);
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
}
|
||||
|
||||
private function seekToTop() : Bamboo{
|
||||
@ -137,7 +147,7 @@ class Bamboo extends Transparent{
|
||||
return $top;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($item instanceof Fertilizer){
|
||||
$top = $this->seekToTop();
|
||||
if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2), $player)){
|
||||
@ -233,8 +243,4 @@ class Bamboo extends Transparent{
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BAMBOO();
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,28 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Bamboo as ItemBamboo;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class BambooSapling extends Flowable{
|
||||
|
||||
private bool $ready = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->ready);
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->ready = ($stateMeta & BlockLegacyMetadata::BAMBOO_SAPLING_FLAG_READY) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->ready ? BlockLegacyMetadata::BAMBOO_SAPLING_FLAG_READY : 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{ return 0b1; }
|
||||
|
||||
public function isReady() : bool{ return $this->ready; }
|
||||
|
||||
/** @return $this */
|
||||
@ -49,11 +54,14 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block->getTypeId() === BlockTypeIds::GRAVEL ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
$block->hasTypeTag(BlockTypeTags::SAND);
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
@ -63,7 +71,7 @@ final class BambooSapling extends Flowable{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($item instanceof Fertilizer || $item instanceof ItemBamboo){
|
||||
if($this->grow($player)){
|
||||
$item->pop();
|
||||
@ -118,6 +126,6 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BAMBOO();
|
||||
return VanillaBlocks::BAMBOO()->asItem();
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Barrel as TileBarrel;
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -38,9 +38,17 @@ class Barrel extends Opaque{
|
||||
|
||||
protected bool $open = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->facing($this->facing);
|
||||
$w->bool($this->open);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeFacing($this->facing) | ($this->open ? BlockLegacyMetadata::BARREL_FLAG_OPEN : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::BARREL_FLAG_OPEN) === BlockLegacyMetadata::BARREL_FLAG_OPEN;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function isOpen() : bool{
|
||||
@ -73,7 +81,7 @@ class Barrel extends Opaque{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$barrel = $this->position->getWorld()->getTile($this->position);
|
||||
if($barrel instanceof TileBarrel){
|
||||
|
@ -28,9 +28,9 @@ use pocketmine\block\utils\BannerPatternLayer;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\item\Banner as ItemBanner;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
@ -48,20 +48,18 @@ abstract class BaseBanner extends Transparent{
|
||||
*/
|
||||
protected array $patterns = [];
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::BLACK();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromWorld() : void{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileBanner){
|
||||
$this->color = $tile->getBaseColor();
|
||||
$this->setPatterns($tile->getPatterns());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -138,6 +136,10 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return DyeColorIdMap::getInstance()->toInvertedId($this->color);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$drop = $this->asItem();
|
||||
if($drop instanceof ItemBanner && count($this->patterns) > 0){
|
||||
@ -154,8 +156,4 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BANNER()->setColor($this->color);
|
||||
}
|
||||
}
|
||||
|
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\FoodSource;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
abstract class BaseCake extends Transparent implements FoodSource{
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::AIR){ //Replace with common break method
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
return $player->consumeObject($this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFoodRestore() : int{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getSaturationRestore() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EffectInstance[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
abstract public function getResidue() : Block;
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $this->getResidue());
|
||||
}
|
||||
}
|
@ -28,28 +28,34 @@ use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
abstract class BaseCoral extends Transparent{
|
||||
use CoralTypeTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
$this->coralType = CoralType::TUBE();
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->dead){
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(40, 200));
|
||||
}
|
||||
}
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
if(!$this->dead && !$this->isCoveredWithWater()){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
$hasWater = false;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$hasWater = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: check water inside the block itself (not supported on the API yet)
|
||||
if(!$hasWater){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,21 +70,6 @@ abstract class BaseCoral extends Transparent{
|
||||
|
||||
public function isSolid() : bool{ return false; }
|
||||
|
||||
protected function isCoveredWithWater() : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$hasWater = false;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$hasWater = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: check water inside the block itself (not supported on the API yet)
|
||||
return $hasWater;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{ return []; }
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
|
@ -1,63 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Arrow;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
abstract class BaseFire extends Flowable{
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, $this->getFireDamage());
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
$ev->cancel();
|
||||
}
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract protected function getFireDamage() : int;
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -24,55 +24,35 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Sign as TileSign;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SignText;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\WoodTypeTrait;
|
||||
use pocketmine\color\Color;
|
||||
use pocketmine\event\block\SignChangeEvent;
|
||||
use pocketmine\item\Dye;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemTypeIds;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\DyeUseSound;
|
||||
use pocketmine\world\sound\InkSacUseSound;
|
||||
use function array_map;
|
||||
use function assert;
|
||||
use function strlen;
|
||||
|
||||
abstract class BaseSign extends Transparent{
|
||||
use WoodTypeTrait;
|
||||
|
||||
protected SignText $text;
|
||||
protected ?int $editorEntityRuntimeId = null;
|
||||
|
||||
/** @var \Closure() : Item */
|
||||
private \Closure $asItemCallback;
|
||||
|
||||
/**
|
||||
* @param \Closure() : Item $asItemCallback
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback){
|
||||
$this->woodType = $woodType;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
$this->text = new SignText();
|
||||
$this->asItemCallback = $asItemCallback;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromWorld() : void{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileSign){
|
||||
$this->text = $tile->getText();
|
||||
$this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -105,7 +85,7 @@ abstract class BaseSign extends Transparent{
|
||||
abstract protected function getSupportingFace() : int;
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->getSupportingFace())->getTypeId() === BlockTypeIds::AIR){
|
||||
if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -117,55 +97,6 @@ abstract class BaseSign extends Transparent{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
private function doSignChange(SignText $newText, Player $player, Item $item) : bool{
|
||||
$ev = new SignChangeEvent($this, $player, $newText);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->text = $ev->getNewText();
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{
|
||||
if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
|
||||
$this->position->getWorld()->addSound($this->position, new InkSacUseSound());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player === null){
|
||||
return false;
|
||||
}
|
||||
$dyeColor = $item instanceof Dye ? $item->getColor() : match($item->getTypeId()){
|
||||
ItemTypeIds::BONE_MEAL => DyeColor::WHITE(),
|
||||
ItemTypeIds::LAPIS_LAZULI => DyeColor::BLUE(),
|
||||
ItemTypeIds::COCOA_BEANS => DyeColor::BROWN(),
|
||||
default => null
|
||||
};
|
||||
if($dyeColor !== null){
|
||||
$color = $dyeColor->equals(DyeColor::BLACK()) ? new Color(0, 0, 0) : $dyeColor->getRgbValue();
|
||||
if($color->toARGB() === $this->text->getBaseColor()->toARGB()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)){
|
||||
$this->position->getWorld()->addSound($this->position, new DyeUseSound());
|
||||
return true;
|
||||
}
|
||||
}elseif($item->getTypeId() === ItemTypeIds::INK_SAC){
|
||||
return $this->changeSignGlowingState(false, $player, $item);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::GLOW_INK_SAC){
|
||||
return $this->changeSignGlowingState(true, $player, $item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about the sign text.
|
||||
*/
|
||||
@ -208,8 +139,4 @@ abstract class BaseSign extends Transparent{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return ($this->asItemCallback)();
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,12 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Bed as TileBed;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
@ -48,26 +49,34 @@ class Bed extends Transparent{
|
||||
protected bool $occupied = false;
|
||||
protected bool $head = false;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::RED();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->occupied);
|
||||
$w->bool($this->head);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) |
|
||||
($this->occupied ? BlockLegacyMetadata::BED_FLAG_OCCUPIED : 0) |
|
||||
($this->head ? BlockLegacyMetadata::BED_FLAG_HEAD : 0);
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->occupied = ($stateMeta & BlockLegacyMetadata::BED_FLAG_OCCUPIED) !== 0;
|
||||
$this->head = ($stateMeta & BlockLegacyMetadata::BED_FLAG_HEAD) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
parent::readStateFromWorld();
|
||||
//read extra state information from the tile - this is an ugly hack
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileBed){
|
||||
$this->color = $tile->getColor();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -123,7 +132,7 @@ class Bed extends Transparent{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$other = $this->getOtherHalf();
|
||||
$playerPos = $player->getPosition();
|
||||
@ -200,6 +209,10 @@ class Bed extends Transparent{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return DyeColorIdMap::getInstance()->toId($this->color);
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
return [$this, $other];
|
||||
@ -211,6 +224,4 @@ class Bed extends Transparent{
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function getMaxStackSize() : int{ return 1; }
|
||||
}
|
||||
|
@ -23,13 +23,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
|
||||
class Bedrock extends Opaque{
|
||||
|
||||
private bool $burnsForever = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->burnsForever);
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->burnsForever = ($stateMeta & BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->burnsForever ? BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN : 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1;
|
||||
}
|
||||
|
||||
public function burnsForever() : bool{
|
||||
|
@ -42,7 +42,7 @@ class Beetroot extends Crops{
|
||||
];
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaItems::BEETROOT_SEEDS();
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,16 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Bell as TileBell;
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\BellRingSound;
|
||||
|
||||
@ -43,14 +43,41 @@ final class Bell extends Transparent{
|
||||
|
||||
private BellAttachmentType $attachmentType;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->attachmentType = BellAttachmentType::FLOOR();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bellAttachmentType($this->attachmentType);
|
||||
$w->horizontalFacing($this->facing);
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->setFacing(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03));
|
||||
|
||||
$attachmentType = [
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR => BellAttachmentType::FLOOR(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_CEILING => BellAttachmentType::CEILING(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL => BellAttachmentType::ONE_WALL(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS => BellAttachmentType::TWO_WALLS()
|
||||
][($stateMeta >> 2) & 0b11] ?? null;
|
||||
if($attachmentType === null){
|
||||
throw new InvalidBlockStateException("No such attachment type");
|
||||
}
|
||||
$this->setAttachmentType($attachmentType);
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
$attachmentTypeMeta = [
|
||||
BellAttachmentType::FLOOR()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR,
|
||||
BellAttachmentType::CEILING()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_CEILING,
|
||||
BellAttachmentType::ONE_WALL()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL,
|
||||
BellAttachmentType::TWO_WALLS()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS
|
||||
][$this->getAttachmentType()->id()] ?? null;
|
||||
if($attachmentTypeMeta === null){
|
||||
throw new AssumptionFailedError("Mapping should cover all cases");
|
||||
}
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->getFacing()) | ($attachmentTypeMeta << 2);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
@ -130,10 +157,17 @@ final class Bell extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$faceHit = Facing::opposite($player->getHorizontalFacing());
|
||||
if($this->isValidFaceToRing($faceHit)){
|
||||
if(
|
||||
$this->attachmentType->equals(BellAttachmentType::CEILING()) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) ||
|
||||
(
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) &&
|
||||
($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true))
|
||||
)
|
||||
){
|
||||
$this->ring($faceHit);
|
||||
return true;
|
||||
}
|
||||
@ -142,13 +176,6 @@ final class Bell extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
$faceHit = Facing::opposite($projectile->getHorizontalFacing());
|
||||
if($this->isValidFaceToRing($faceHit)){
|
||||
$this->ring($faceHit);
|
||||
}
|
||||
}
|
||||
|
||||
public function ring(int $faceHit) : void{
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position, new BellRingSound());
|
||||
@ -157,15 +184,4 @@ final class Bell extends Transparent{
|
||||
$world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
|
||||
}
|
||||
}
|
||||
|
||||
private function isValidFaceToRing(int $faceHit) : bool{
|
||||
return (
|
||||
$this->attachmentType->equals(BellAttachmentType::CEILING()) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) ||
|
||||
(
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) &&
|
||||
($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -28,61 +28,49 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Spawnable;
|
||||
use pocketmine\block\tile\Tile;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataSizeCalculator;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\item\enchantment\VanillaEnchantments;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemBlock;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\World;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function get_class;
|
||||
use function dechex;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class Block{
|
||||
public const INTERNAL_STATE_DATA_BITS = 8;
|
||||
public const INTERNAL_STATE_DATA_MASK = ~(~0 << self::INTERNAL_STATE_DATA_BITS);
|
||||
public const INTERNAL_METADATA_BITS = 4;
|
||||
public const INTERNAL_METADATA_MASK = ~(~0 << self::INTERNAL_METADATA_BITS);
|
||||
|
||||
protected BlockIdentifier $idInfo;
|
||||
protected string $fallbackName;
|
||||
protected BlockTypeInfo $typeInfo;
|
||||
protected BlockBreakInfo $breakInfo;
|
||||
protected Position $position;
|
||||
|
||||
/** @var AxisAlignedBB[]|null */
|
||||
protected ?array $collisionBoxes = null;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<string, int>
|
||||
*/
|
||||
private static array $typeDataBits = [];
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<string, int>
|
||||
*/
|
||||
private static array $stateDataBits = [];
|
||||
|
||||
/**
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){
|
||||
throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask()));
|
||||
}
|
||||
$this->idInfo = $idInfo;
|
||||
$this->fallbackName = $name;
|
||||
$this->typeInfo = $typeInfo;
|
||||
$this->breakInfo = $breakInfo;
|
||||
$this->position = new Position(0, 0, 0, null);
|
||||
}
|
||||
|
||||
@ -91,8 +79,8 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about how to identify and store this block type, such as type ID and
|
||||
* tile type (if any).
|
||||
* Returns an object containing information about how to identify and store this block type, such as its legacy
|
||||
* numeric ID(s), tile type (if any), and legacy variant metadata.
|
||||
*/
|
||||
public function getIdInfo() : BlockIdentifier{
|
||||
return $this->idInfo;
|
||||
@ -106,16 +94,12 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type ID that identifies this type of block. This allows comparing basic block types, e.g. wool, stone,
|
||||
* glass, etc.
|
||||
* @deprecated
|
||||
*
|
||||
* This does **NOT** include information like facing, open/closed, powered/unpowered, colour, etc. This means that,
|
||||
* for example, red wool and green wool have the same type ID.
|
||||
*
|
||||
* @see BlockTypeIds
|
||||
* Returns the legacy numeric Minecraft block ID.
|
||||
*/
|
||||
public function getTypeId() : int{
|
||||
return $this->idInfo->getBlockTypeId();
|
||||
public function getId() : int{
|
||||
return $this->idInfo->getBlockId();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,48 +108,10 @@ class Block{
|
||||
* Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store
|
||||
* blocks in chunks at runtime.
|
||||
*
|
||||
* This usually encodes all properties of the block, such as facing, open/closed, powered/unpowered, colour, etc.
|
||||
* However, some blocks (such as signs and chests) may store additional properties in an associated "tile" if they
|
||||
* have too many possible values to be encoded into the state ID. These extra properties are **NOT** included in
|
||||
* this function's result.
|
||||
*
|
||||
* This ID can be used to later obtain a copy of this block using {@link RuntimeBlockStateRegistry::fromStateId()}.
|
||||
* This ID can be used to later obtain a copy of this block using {@link BlockFactory::get()}.
|
||||
*/
|
||||
public function getStateId() : int{
|
||||
return ($this->getTypeId() << self::INTERNAL_STATE_DATA_BITS) | $this->computeTypeAndStateData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given block has an equivalent type to this one. This compares the type IDs.
|
||||
*/
|
||||
public function isSameType(Block $other) : bool{
|
||||
return $this->getTypeId() === $other->getTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given block has the same type and properties as this block.
|
||||
*/
|
||||
public function isSameState(Block $other) : bool{
|
||||
return $this->getStateId() === $other->getStateId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTypeTags() : array{
|
||||
return $this->typeInfo->getTypeTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block type has the given type tag. Type tags are used as a dynamic way to tag blocks as
|
||||
* having certain properties, allowing type checks which are more dynamic than hardcoding a bunch of IDs or a bunch
|
||||
* of instanceof checks.
|
||||
*
|
||||
* For example, grass blocks, dirt, farmland, podzol and mycelium are all dirt-like blocks, and support the
|
||||
* placement of blocks like flowers, so they have a common tag which allows them to be identified as such.
|
||||
*/
|
||||
public function hasTypeTag(string $tag) : bool{
|
||||
return $this->typeInfo->hasTypeTag($tag);
|
||||
public function getFullId() : int{
|
||||
return ($this->getId() << self::INTERNAL_METADATA_BITS) | $this->getMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,114 +120,44 @@ class Block{
|
||||
* Type information such as colour, wood type, etc. is preserved.
|
||||
*/
|
||||
public function asItem() : Item{
|
||||
return new ItemBlock($this);
|
||||
}
|
||||
|
||||
final public function getRequiredTypeDataBits() : int{
|
||||
$class = get_class($this);
|
||||
if(isset(self::$typeDataBits[$class])){
|
||||
return self::$typeDataBits[$class];
|
||||
}
|
||||
$calculator = new RuntimeDataSizeCalculator();
|
||||
$this->describeType($calculator);
|
||||
return self::$typeDataBits[$class] = $calculator->getBitsUsed();
|
||||
}
|
||||
|
||||
final public function getRequiredStateDataBits() : int{
|
||||
$class = get_class($this);
|
||||
if(isset(self::$stateDataBits[$class])){
|
||||
return self::$stateDataBits[$class];
|
||||
}
|
||||
$calculator = new RuntimeDataSizeCalculator();
|
||||
$this->describeState($calculator);
|
||||
return self::$stateDataBits[$class] = $calculator->getBitsUsed();
|
||||
return ItemFactory::getInstance()->get(
|
||||
$this->idInfo->getItemId(),
|
||||
$this->idInfo->getVariant() | $this->writeStateToItemMeta()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function decodeTypeData(int $data) : void{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$reader = new RuntimeDataReader($typeBits, $data);
|
||||
|
||||
$this->describeType($reader);
|
||||
$readBits = $reader->getOffset();
|
||||
if($typeBits !== $readBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $typeBits bits of type data were provided, but $readBits were read");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function decodeTypeAndStateData(int $data) : void{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$stateBits = $this->getRequiredStateDataBits();
|
||||
$reader = new RuntimeDataReader($typeBits + $stateBits, $data);
|
||||
$this->decodeTypeData($reader->readInt($typeBits));
|
||||
|
||||
$this->describeState($reader);
|
||||
$readBits = $reader->getOffset() - $typeBits;
|
||||
if($stateBits !== $readBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were provided, but $readBits were read");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function computeTypeData() : int{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$writer = new RuntimeDataWriter($typeBits);
|
||||
|
||||
$this->describeType($writer);
|
||||
$writtenBits = $writer->getOffset();
|
||||
if($typeBits !== $writtenBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $typeBits bits of type data were expected, but $writtenBits were written");
|
||||
}
|
||||
|
||||
return $writer->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function computeTypeAndStateData() : int{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$stateBits = $this->getRequiredStateDataBits();
|
||||
$writer = new RuntimeDataWriter($typeBits + $stateBits);
|
||||
$writer->writeInt($typeBits, $this->computeTypeData());
|
||||
|
||||
$this->describeState($writer);
|
||||
$writtenBits = $writer->getOffset() - $typeBits;
|
||||
if($stateBits !== $writtenBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were expected, but $writtenBits were written");
|
||||
}
|
||||
|
||||
return $writer->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes properties of this block which apply to both the block and item form of the block.
|
||||
* Examples of suitable properties include colour, skull type, and any other information which **IS** kept when the
|
||||
* block is mined or block-picked.
|
||||
* @deprecated
|
||||
*
|
||||
* The method implementation must NOT use conditional logic to determine which properties are written. It must
|
||||
* always write the same properties in the same order, regardless of the current state of the block.
|
||||
* Returns the legacy Minecraft block meta value. This is a mixed-purpose value, which is used to store different
|
||||
* things for different blocks.
|
||||
*/
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
//NOOP
|
||||
public function getMeta() : int{
|
||||
$stateMeta = $this->writeStateToMeta();
|
||||
assert(($stateMeta & ~$this->getStateBitmask()) === 0);
|
||||
return $this->idInfo->getVariant() | $stateMeta;
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes properties of this block which apply only to the block form of the block.
|
||||
* Examples of suitable properties include facing, open/closed, powered/unpowered, on/off, and any other information
|
||||
* which **IS NOT** kept when the block is mined or block-picked.
|
||||
*
|
||||
* The method implementation must NOT use conditional logic to determine which properties are written. It must
|
||||
* always write the same properties in the same order, regardless of the current state of the block.
|
||||
* Returns a bitmask used to extract state bits from block metadata.
|
||||
* This is used to remove unwanted information from the legacy meta value when getting the block as an item.
|
||||
*/
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
public function getStateBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidBlockStateException
|
||||
*/
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
@ -291,14 +167,9 @@ class Block{
|
||||
*
|
||||
* Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
|
||||
* AABBs and force recalculation.
|
||||
*
|
||||
* A replacement block may be returned. This is useful if the block type changed due to reading of world data (e.g.
|
||||
* data from a block entity).
|
||||
*/
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromWorld() : void{
|
||||
$this->collisionBoxes = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,11 +180,7 @@ class Block{
|
||||
*/
|
||||
public function writeStateToWorld() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$chunk = $world->getOrLoadChunkAtPosition($this->position);
|
||||
if($chunk === null){
|
||||
throw new AssumptionFailedError("World::setBlock() should have loaded the chunk before calling this method");
|
||||
}
|
||||
$chunk->setBlockStateId($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getStateId());
|
||||
$world->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId());
|
||||
|
||||
$tileType = $this->idInfo->getTileClass();
|
||||
$oldTile = $world->getTile($this->position);
|
||||
@ -335,6 +202,31 @@ class Block{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type ID that identifies this type of block. This does not include information like facing, open/closed,
|
||||
* powered/unpowered, etc.
|
||||
*/
|
||||
public function getTypeId() : int{
|
||||
return ($this->idInfo->getBlockId() << Block::INTERNAL_METADATA_BITS) | $this->idInfo->getVariant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given block has an equivalent type to this one. This compares the type IDs.
|
||||
*
|
||||
* Note: This ignores additional IDs used to represent additional states. This means that, for example, a lit
|
||||
* furnace and unlit furnace are considered the same type.
|
||||
*/
|
||||
public function isSameType(Block $other) : bool{
|
||||
return $this->getTypeId() === $other->getTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given block has the same type and properties as this block.
|
||||
*/
|
||||
public function isSameState(Block $other) : bool{
|
||||
return $this->getFullId() === $other->getFullId();
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isPlaceable
|
||||
*/
|
||||
@ -388,15 +280,13 @@ class Block{
|
||||
* Returns an object containing information about the destruction requirements of this block.
|
||||
*/
|
||||
public function getBreakInfo() : BlockBreakInfo{
|
||||
return $this->typeInfo->getBreakInfo();
|
||||
return $this->breakInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*
|
||||
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if full)
|
||||
*/
|
||||
public function onBreak(Item $item, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onBreak(Item $item, ?Player $player = null) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
if(($t = $world->getTile($this->position)) !== null){
|
||||
$t->onBlockDestroyed();
|
||||
@ -436,10 +326,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)
|
||||
*/
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -531,7 +419,7 @@ class Block{
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->getBreakInfo()->isToolCompatible($item)){
|
||||
if($this->breakInfo->isToolCompatible($item)){
|
||||
if($this->isAffectedBySilkTouch() && $item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){
|
||||
return $this->getSilkTouchDrops($item);
|
||||
}
|
||||
@ -573,7 +461,7 @@ class Block{
|
||||
* Returns how much XP will be dropped by breaking this block with the given item.
|
||||
*/
|
||||
public function getXpDropForTool(Item $item) : int{
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->getBreakInfo()->isToolCompatible($item)){
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->breakInfo->isToolCompatible($item)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -627,10 +515,6 @@ class Block{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function isFireProofAsItem() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching
|
||||
* fire.
|
||||
@ -720,7 +604,7 @@ class Block{
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(){
|
||||
return "Block[" . $this->getName() . "] (" . $this->getTypeId() . ":" . $this->computeTypeAndStateData() . ")";
|
||||
return "Block[" . $this->getName() . "] (" . $this->getId() . ":" . $this->getMeta() . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -779,13 +663,6 @@ class Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a projectile collides with one of this block's collision boxes.
|
||||
*/
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of collision bounding boxes for this block.
|
||||
* These are used for:
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ToolTier;
|
||||
use function get_class;
|
||||
|
||||
class BlockBreakInfo{
|
||||
@ -53,22 +52,6 @@ class BlockBreakInfo{
|
||||
$this->blastResistance = $blastResistance ?? $hardness * 5;
|
||||
}
|
||||
|
||||
public static function tier(float $hardness, int $toolType, ToolTier $toolTier, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, $toolType, $toolTier->getHarvestLevel(), $blastResistance);
|
||||
}
|
||||
|
||||
public static function pickaxe(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::PICKAXE, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function shovel(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::SHOVEL, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function axe(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::AXE, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function instant(int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0) : self{
|
||||
return new self(0.0, $toolType, $toolHarvestLevel, 0.0);
|
||||
}
|
||||
|
1090
src/block/BlockFactory.php
Normal file
1090
src/block/BlockFactory.php
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,18 +31,34 @@ class BlockIdentifier{
|
||||
* @phpstan-param class-string<Tile>|null $tileClass
|
||||
*/
|
||||
public function __construct(
|
||||
private int $blockTypeId,
|
||||
private int $blockId,
|
||||
private int $variant,
|
||||
private ?int $itemId = null,
|
||||
private ?string $tileClass = null
|
||||
){
|
||||
if($blockTypeId < 0){
|
||||
throw new \InvalidArgumentException("Block type ID may not be negative");
|
||||
}
|
||||
if($tileClass !== null){
|
||||
Utils::testValidInstance($tileClass, Tile::class);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBlockTypeId() : int{ return $this->blockTypeId; }
|
||||
public function getBlockId() : int{
|
||||
return $this->blockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAllBlockIds() : array{
|
||||
return [$this->blockId];
|
||||
}
|
||||
|
||||
public function getVariant() : int{
|
||||
return $this->variant;
|
||||
}
|
||||
|
||||
public function getItemId() : int{
|
||||
return $this->itemId ?? ($this->blockId > 255 ? 255 - $this->blockId : $this->blockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return class-string<Tile>|null
|
||||
|
59
src/block/BlockIdentifierFlattened.php
Normal file
59
src/block/BlockIdentifierFlattened.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use function count;
|
||||
|
||||
class BlockIdentifierFlattened extends BlockIdentifier{
|
||||
|
||||
/** @var int[] */
|
||||
private array $additionalIds;
|
||||
|
||||
/**
|
||||
* @param int[] $additionalIds
|
||||
*/
|
||||
public function __construct(int $blockId, array $additionalIds, int $variant, ?int $itemId = null, ?string $tileClass = null){
|
||||
if(count($additionalIds) === 0){
|
||||
throw new \InvalidArgumentException("Expected at least 1 additional ID");
|
||||
}
|
||||
parent::__construct($blockId, $variant, $itemId, $tileClass);
|
||||
|
||||
$this->additionalIds = $additionalIds;
|
||||
}
|
||||
|
||||
public function getAdditionalId(int $index) : int{
|
||||
if(!isset($this->additionalIds[$index])){
|
||||
throw new \InvalidArgumentException("No such ID at index $index");
|
||||
}
|
||||
return $this->additionalIds[$index];
|
||||
}
|
||||
|
||||
public function getSecondId() : int{
|
||||
return $this->getAdditionalId(0);
|
||||
}
|
||||
|
||||
public function getAllBlockIds() : array{
|
||||
return [$this->getBlockId(), ...$this->additionalIds];
|
||||
}
|
||||
}
|
@ -24,270 +24,225 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\BlockIdentifier as BID;
|
||||
use pocketmine\block\BlockTypeIds as Ids;
|
||||
use pocketmine\block\BlockLegacyIds as Ids;
|
||||
use pocketmine\block\tile\Sign as TileSign;
|
||||
use pocketmine\block\utils\LeavesType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\item\ItemIds;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
|
||||
final class BlockLegacyIdHelper{
|
||||
|
||||
public static function getWoodenPlanksIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_PLANKS,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_PLANKS,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_PLANKS,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_PLANKS,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_PLANKS,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_PLANKS,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_PLANKS,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_PLANKS,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_PLANKS,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenFenceIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_FENCE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_FENCE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_FENCE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_FENCE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_FENCE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_FENCE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_FENCE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_FENCE,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenSlabIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_SLAB,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_SLAB,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_SLAB,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_SLAB,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_SLAB,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_SLAB,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_SLAB,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_SLAB,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_SLAB,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getLogIdentifier(WoodType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_LOG,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_LOG,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_LOG,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_LOG,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_LOG,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_LOG,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_LOG,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_STEM,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_STEM,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getAllSidedLogIdentifier(WoodType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_WOOD,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_WOOD,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_WOOD,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_WOOD,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_WOOD,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_WOOD,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_WOOD,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_HYPHAE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_HYPHAE,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getLeavesIdentifier(LeavesType $leavesType) : BID{
|
||||
return new BID(match($leavesType->id()){
|
||||
LeavesType::OAK()->id() => Ids::OAK_LEAVES,
|
||||
LeavesType::SPRUCE()->id() => Ids::SPRUCE_LEAVES,
|
||||
LeavesType::BIRCH()->id() => Ids::BIRCH_LEAVES,
|
||||
LeavesType::JUNGLE()->id() => Ids::JUNGLE_LEAVES,
|
||||
LeavesType::ACACIA()->id() => Ids::ACACIA_LEAVES,
|
||||
LeavesType::DARK_OAK()->id() => Ids::DARK_OAK_LEAVES,
|
||||
LeavesType::MANGROVE()->id() => Ids::MANGROVE_LEAVES,
|
||||
LeavesType::AZALEA()->id() => Ids::AZALEA_LEAVES,
|
||||
LeavesType::FLOWERING_AZALEA()->id() => Ids::FLOWERING_AZALEA_LEAVES,
|
||||
default => throw new AssumptionFailedError("All leaves types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getSaplingIdentifier(TreeType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
TreeType::OAK()->id() => Ids::OAK_SAPLING,
|
||||
TreeType::SPRUCE()->id() => Ids::SPRUCE_SAPLING,
|
||||
TreeType::BIRCH()->id() => Ids::BIRCH_SAPLING,
|
||||
TreeType::JUNGLE()->id() => Ids::JUNGLE_SAPLING,
|
||||
TreeType::ACACIA()->id() => Ids::ACACIA_SAPLING,
|
||||
TreeType::DARK_OAK()->id() => Ids::DARK_OAK_SAPLING,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BID[]|\Closure[]
|
||||
* @phpstan-return array{BID, BID, \Closure() : \pocketmine\item\Item}
|
||||
*/
|
||||
public static function getWoodenSignInfo(WoodType $treeType) : array{
|
||||
public static function getWoodenFloorSignIdentifier(TreeType $treeType) : BID{
|
||||
switch($treeType->id()){
|
||||
case WoodType::OAK()->id():
|
||||
return [
|
||||
new BID(Ids::OAK_SIGN, TileSign::class),
|
||||
new BID(Ids::OAK_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::OAK_SIGN()
|
||||
];
|
||||
case WoodType::SPRUCE()->id():
|
||||
return [
|
||||
new BID(Ids::SPRUCE_SIGN, TileSign::class),
|
||||
new BID(Ids::SPRUCE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::SPRUCE_SIGN()
|
||||
];
|
||||
case WoodType::BIRCH()->id():
|
||||
return [
|
||||
new BID(Ids::BIRCH_SIGN, TileSign::class),
|
||||
new BID(Ids::BIRCH_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::BIRCH_SIGN()
|
||||
];
|
||||
case WoodType::JUNGLE()->id():
|
||||
return [
|
||||
new BID(Ids::JUNGLE_SIGN, TileSign::class),
|
||||
new BID(Ids::JUNGLE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::JUNGLE_SIGN()
|
||||
];
|
||||
case WoodType::ACACIA()->id():
|
||||
return [
|
||||
new BID(Ids::ACACIA_SIGN, TileSign::class),
|
||||
new BID(Ids::ACACIA_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::ACACIA_SIGN()
|
||||
];
|
||||
case WoodType::DARK_OAK()->id():
|
||||
return [
|
||||
new BID(Ids::DARK_OAK_SIGN, TileSign::class),
|
||||
new BID(Ids::DARK_OAK_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::DARK_OAK_SIGN()
|
||||
];
|
||||
case WoodType::MANGROVE()->id():
|
||||
return [
|
||||
new BID(Ids::MANGROVE_SIGN, TileSign::class),
|
||||
new BID(Ids::MANGROVE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::MANGROVE_SIGN()
|
||||
];
|
||||
case WoodType::CRIMSON()->id():
|
||||
return [
|
||||
new BID(Ids::CRIMSON_SIGN, TileSign::class),
|
||||
new BID(Ids::CRIMSON_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::CRIMSON_SIGN()
|
||||
];
|
||||
case WoodType::WARPED()->id():
|
||||
return [
|
||||
new BID(Ids::WARPED_SIGN, TileSign::class),
|
||||
new BID(Ids::WARPED_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::WARPED_SIGN()
|
||||
];
|
||||
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::SIGN_POST, 0, ItemIds::SIGN, TileSign::class);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_STANDING_SIGN,0, ItemIds::ACACIA_SIGN, TileSign::class);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenTrapdoorIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_TRAPDOOR,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_TRAPDOOR,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_TRAPDOOR,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_TRAPDOOR,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_TRAPDOOR,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_TRAPDOOR,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_TRAPDOOR,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_TRAPDOOR,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_TRAPDOOR,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenWallSignIdentifier(TreeType $treeType) : BID{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenButtonIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_BUTTON,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_BUTTON,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_BUTTON,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_BUTTON,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_BUTTON,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_BUTTON,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_BUTTON,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_BUTTON,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_BUTTON,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenTrapdoorIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_TRAPDOOR, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_TRAPDOOR, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_TRAPDOOR, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_TRAPDOOR, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_TRAPDOOR, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_TRAPDOOR, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenPressurePlateIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_PRESSURE_PLATE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_PRESSURE_PLATE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_PRESSURE_PLATE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_PRESSURE_PLATE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_PRESSURE_PLATE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_PRESSURE_PLATE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_PRESSURE_PLATE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_PRESSURE_PLATE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_PRESSURE_PLATE,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenButtonIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_BUTTON, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_BUTTON, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_BUTTON, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_BUTTON, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_BUTTON, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_BUTTON, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenDoorIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_DOOR,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_DOOR,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_DOOR,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_DOOR,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_DOOR,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_DOOR,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_DOOR,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_DOOR,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_DOOR,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenPressurePlateIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_PRESSURE_PLATE, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_PRESSURE_PLATE, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_PRESSURE_PLATE, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_PRESSURE_PLATE, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_PRESSURE_PLATE, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_PRESSURE_PLATE, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenFenceGateIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_FENCE_GATE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_FENCE_GATE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_FENCE_GATE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_FENCE_GATE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_FENCE_GATE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE_GATE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_FENCE_GATE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_FENCE_GATE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_FENCE_GATE,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenDoorIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenStairsIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_STAIRS,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_STAIRS,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_STAIRS,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_STAIRS,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_STAIRS,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_STAIRS,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_STAIRS,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_STAIRS,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_STAIRS,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
public static function getWoodenFenceIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::OAK_FENCE_GATE, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_FENCE_GATE, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_FENCE_GATE, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_FENCE_GATE, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_FENCE_GATE, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_FENCE_GATE, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenStairsIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::OAK_STAIRS, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_STAIRS, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_STAIRS, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_STAIRS, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_STAIRS, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_STAIRS, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getStrippedLogIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_OAK_LOG, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_SPRUCE_LOG, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_BIRCH_LOG, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_JUNGLE_LOG, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_ACACIA_LOG, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_DARK_OAK_LOG, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getGlazedTerracottaIdentifier(DyeColor $color) : BlockIdentifier{
|
||||
switch($color->id()){
|
||||
case DyeColor::WHITE()->id():
|
||||
return new BlockIdentifier(Ids::WHITE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::ORANGE()->id():
|
||||
return new BlockIdentifier(Ids::ORANGE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::MAGENTA()->id():
|
||||
return new BlockIdentifier(Ids::MAGENTA_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIGHT_BLUE()->id():
|
||||
return new BlockIdentifier(Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::YELLOW()->id():
|
||||
return new BlockIdentifier(Ids::YELLOW_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIME()->id():
|
||||
return new BlockIdentifier(Ids::LIME_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::PINK()->id():
|
||||
return new BlockIdentifier(Ids::PINK_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::GRAY()->id():
|
||||
return new BlockIdentifier(Ids::GRAY_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIGHT_GRAY()->id():
|
||||
return new BlockIdentifier(Ids::SILVER_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::CYAN()->id():
|
||||
return new BlockIdentifier(Ids::CYAN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::PURPLE()->id():
|
||||
return new BlockIdentifier(Ids::PURPLE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BLUE()->id():
|
||||
return new BlockIdentifier(Ids::BLUE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BROWN()->id():
|
||||
return new BlockIdentifier(Ids::BROWN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::GREEN()->id():
|
||||
return new BlockIdentifier(Ids::GREEN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::RED()->id():
|
||||
return new BlockIdentifier(Ids::RED_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BLACK()->id():
|
||||
return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all colours");
|
||||
}
|
||||
|
||||
public static function getStoneSlabIdentifier(int $stoneSlabId, int $meta) : BlockIdentifierFlattened{
|
||||
$id = [
|
||||
1 => [Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB],
|
||||
2 => [Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2],
|
||||
3 => [Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3],
|
||||
4 => [Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4]
|
||||
][$stoneSlabId] ?? null;
|
||||
if($id === null){
|
||||
throw new \InvalidArgumentException("Stone slab type should be 1, 2, 3 or 4");
|
||||
}
|
||||
return new BlockIdentifierFlattened($id[0], [$id[1]], $meta);
|
||||
}
|
||||
}
|
||||
|
501
src/block/BlockLegacyIds.php
Normal file
501
src/block/BlockLegacyIds.php
Normal file
@ -0,0 +1,501 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
final class BlockLegacyIds{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const AIR = 0;
|
||||
public const STONE = 1;
|
||||
public const GRASS = 2;
|
||||
public const DIRT = 3;
|
||||
public const COBBLESTONE = 4;
|
||||
public const PLANKS = 5, WOODEN_PLANKS = 5;
|
||||
public const SAPLING = 6;
|
||||
public const BEDROCK = 7;
|
||||
public const FLOWING_WATER = 8;
|
||||
public const STILL_WATER = 9, WATER = 9;
|
||||
public const FLOWING_LAVA = 10;
|
||||
public const LAVA = 11, STILL_LAVA = 11;
|
||||
public const SAND = 12;
|
||||
public const GRAVEL = 13;
|
||||
public const GOLD_ORE = 14;
|
||||
public const IRON_ORE = 15;
|
||||
public const COAL_ORE = 16;
|
||||
public const LOG = 17;
|
||||
public const LEAVES = 18;
|
||||
public const SPONGE = 19;
|
||||
public const GLASS = 20;
|
||||
public const LAPIS_ORE = 21;
|
||||
public const LAPIS_BLOCK = 22;
|
||||
public const DISPENSER = 23;
|
||||
public const SANDSTONE = 24;
|
||||
public const NOTEBLOCK = 25, NOTE_BLOCK = 25;
|
||||
public const BED_BLOCK = 26;
|
||||
public const GOLDEN_RAIL = 27, POWERED_RAIL = 27;
|
||||
public const DETECTOR_RAIL = 28;
|
||||
public const STICKY_PISTON = 29;
|
||||
public const COBWEB = 30, WEB = 30;
|
||||
public const TALLGRASS = 31, TALL_GRASS = 31;
|
||||
public const DEADBUSH = 32, DEAD_BUSH = 32;
|
||||
public const PISTON = 33;
|
||||
public const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34;
|
||||
public const WOOL = 35;
|
||||
public const ELEMENT_0 = 36;
|
||||
public const DANDELION = 37, YELLOW_FLOWER = 37;
|
||||
public const POPPY = 38, RED_FLOWER = 38;
|
||||
public const BROWN_MUSHROOM = 39;
|
||||
public const RED_MUSHROOM = 40;
|
||||
public const GOLD_BLOCK = 41;
|
||||
public const IRON_BLOCK = 42;
|
||||
public const DOUBLE_STONE_SLAB = 43;
|
||||
public const STONE_SLAB = 44;
|
||||
public const BRICK_BLOCK = 45;
|
||||
public const TNT = 46;
|
||||
public const BOOKSHELF = 47;
|
||||
public const MOSSY_COBBLESTONE = 48, MOSS_STONE = 48;
|
||||
public const OBSIDIAN = 49;
|
||||
public const TORCH = 50;
|
||||
public const FIRE = 51;
|
||||
public const MOB_SPAWNER = 52, MONSTER_SPAWNER = 52;
|
||||
public const OAK_STAIRS = 53, WOODEN_STAIRS = 53;
|
||||
public const CHEST = 54;
|
||||
public const REDSTONE_WIRE = 55;
|
||||
public const DIAMOND_ORE = 56;
|
||||
public const DIAMOND_BLOCK = 57;
|
||||
public const CRAFTING_TABLE = 58, WORKBENCH = 58;
|
||||
public const WHEAT_BLOCK = 59;
|
||||
public const FARMLAND = 60;
|
||||
public const FURNACE = 61;
|
||||
public const BURNING_FURNACE = 62, LIT_FURNACE = 62;
|
||||
public const SIGN_POST = 63, STANDING_SIGN = 63;
|
||||
public const OAK_DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64;
|
||||
public const LADDER = 65;
|
||||
public const RAIL = 66;
|
||||
public const COBBLESTONE_STAIRS = 67, STONE_STAIRS = 67;
|
||||
public const WALL_SIGN = 68;
|
||||
public const LEVER = 69;
|
||||
public const STONE_PRESSURE_PLATE = 70;
|
||||
public const IRON_DOOR_BLOCK = 71;
|
||||
public const WOODEN_PRESSURE_PLATE = 72;
|
||||
public const REDSTONE_ORE = 73;
|
||||
public const GLOWING_REDSTONE_ORE = 74, LIT_REDSTONE_ORE = 74;
|
||||
public const UNLIT_REDSTONE_TORCH = 75;
|
||||
public const LIT_REDSTONE_TORCH = 76, REDSTONE_TORCH = 76;
|
||||
public const STONE_BUTTON = 77;
|
||||
public const SNOW_LAYER = 78;
|
||||
public const ICE = 79;
|
||||
public const SNOW = 80, SNOW_BLOCK = 80;
|
||||
public const CACTUS = 81;
|
||||
public const CLAY_BLOCK = 82;
|
||||
public const REEDS_BLOCK = 83, SUGARCANE_BLOCK = 83;
|
||||
public const JUKEBOX = 84;
|
||||
public const FENCE = 85;
|
||||
public const PUMPKIN = 86;
|
||||
public const NETHERRACK = 87;
|
||||
public const SOUL_SAND = 88;
|
||||
public const GLOWSTONE = 89;
|
||||
public const PORTAL = 90;
|
||||
public const JACK_O_LANTERN = 91, LIT_PUMPKIN = 91;
|
||||
public const CAKE_BLOCK = 92;
|
||||
public const REPEATER_BLOCK = 93, UNPOWERED_REPEATER = 93;
|
||||
public const POWERED_REPEATER = 94;
|
||||
public const INVISIBLEBEDROCK = 95, INVISIBLE_BEDROCK = 95;
|
||||
public const TRAPDOOR = 96, WOODEN_TRAPDOOR = 96;
|
||||
public const MONSTER_EGG = 97;
|
||||
public const STONEBRICK = 98, STONE_BRICK = 98, STONE_BRICKS = 98;
|
||||
public const BROWN_MUSHROOM_BLOCK = 99;
|
||||
public const RED_MUSHROOM_BLOCK = 100;
|
||||
public const IRON_BARS = 101;
|
||||
public const GLASS_PANE = 102;
|
||||
public const MELON_BLOCK = 103;
|
||||
public const PUMPKIN_STEM = 104;
|
||||
public const MELON_STEM = 105;
|
||||
public const VINE = 106, VINES = 106;
|
||||
public const FENCE_GATE = 107, OAK_FENCE_GATE = 107;
|
||||
public const BRICK_STAIRS = 108;
|
||||
public const STONE_BRICK_STAIRS = 109;
|
||||
public const MYCELIUM = 110;
|
||||
public const LILY_PAD = 111, WATERLILY = 111, WATER_LILY = 111;
|
||||
public const NETHER_BRICK_BLOCK = 112;
|
||||
public const NETHER_BRICK_FENCE = 113;
|
||||
public const NETHER_BRICK_STAIRS = 114;
|
||||
public const NETHER_WART_PLANT = 115;
|
||||
public const ENCHANTING_TABLE = 116, ENCHANTMENT_TABLE = 116;
|
||||
public const BREWING_STAND_BLOCK = 117;
|
||||
public const CAULDRON_BLOCK = 118;
|
||||
public const END_PORTAL = 119;
|
||||
public const END_PORTAL_FRAME = 120;
|
||||
public const END_STONE = 121;
|
||||
public const DRAGON_EGG = 122;
|
||||
public const REDSTONE_LAMP = 123;
|
||||
public const LIT_REDSTONE_LAMP = 124;
|
||||
public const DROPPER = 125;
|
||||
public const ACTIVATOR_RAIL = 126;
|
||||
public const COCOA = 127, COCOA_BLOCK = 127;
|
||||
public const SANDSTONE_STAIRS = 128;
|
||||
public const EMERALD_ORE = 129;
|
||||
public const ENDER_CHEST = 130;
|
||||
public const TRIPWIRE_HOOK = 131;
|
||||
public const TRIPWIRE = 132, TRIP_WIRE = 132;
|
||||
public const EMERALD_BLOCK = 133;
|
||||
public const SPRUCE_STAIRS = 134;
|
||||
public const BIRCH_STAIRS = 135;
|
||||
public const JUNGLE_STAIRS = 136;
|
||||
public const COMMAND_BLOCK = 137;
|
||||
public const BEACON = 138;
|
||||
public const COBBLESTONE_WALL = 139, STONE_WALL = 139;
|
||||
public const FLOWER_POT_BLOCK = 140;
|
||||
public const CARROTS = 141, CARROT_BLOCK = 141;
|
||||
public const POTATOES = 142, POTATO_BLOCK = 142;
|
||||
public const WOODEN_BUTTON = 143;
|
||||
public const MOB_HEAD_BLOCK = 144, SKULL_BLOCK = 144;
|
||||
public const ANVIL = 145;
|
||||
public const TRAPPED_CHEST = 146;
|
||||
public const LIGHT_WEIGHTED_PRESSURE_PLATE = 147;
|
||||
public const HEAVY_WEIGHTED_PRESSURE_PLATE = 148;
|
||||
public const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR = 149;
|
||||
public const POWERED_COMPARATOR = 150;
|
||||
public const DAYLIGHT_DETECTOR = 151, DAYLIGHT_SENSOR = 151;
|
||||
public const REDSTONE_BLOCK = 152;
|
||||
public const NETHER_QUARTZ_ORE = 153, QUARTZ_ORE = 153;
|
||||
public const HOPPER_BLOCK = 154;
|
||||
public const QUARTZ_BLOCK = 155;
|
||||
public const QUARTZ_STAIRS = 156;
|
||||
public const DOUBLE_WOODEN_SLAB = 157;
|
||||
public const WOODEN_SLAB = 158;
|
||||
public const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159;
|
||||
public const STAINED_GLASS_PANE = 160;
|
||||
public const LEAVES2 = 161;
|
||||
public const LOG2 = 162;
|
||||
public const ACACIA_STAIRS = 163;
|
||||
public const DARK_OAK_STAIRS = 164;
|
||||
public const SLIME = 165, SLIME_BLOCK = 165;
|
||||
public const GLOW_STICK = 166;
|
||||
public const IRON_TRAPDOOR = 167;
|
||||
public const PRISMARINE = 168;
|
||||
public const SEALANTERN = 169, SEA_LANTERN = 169;
|
||||
public const HAY_BALE = 170, HAY_BLOCK = 170;
|
||||
public const CARPET = 171;
|
||||
public const HARDENED_CLAY = 172;
|
||||
public const COAL_BLOCK = 173;
|
||||
public const PACKED_ICE = 174;
|
||||
public const DOUBLE_PLANT = 175;
|
||||
public const STANDING_BANNER = 176;
|
||||
public const WALL_BANNER = 177;
|
||||
public const DAYLIGHT_DETECTOR_INVERTED = 178, DAYLIGHT_SENSOR_INVERTED = 178;
|
||||
public const RED_SANDSTONE = 179;
|
||||
public const RED_SANDSTONE_STAIRS = 180;
|
||||
public const DOUBLE_STONE_SLAB2 = 181;
|
||||
public const STONE_SLAB2 = 182;
|
||||
public const SPRUCE_FENCE_GATE = 183;
|
||||
public const BIRCH_FENCE_GATE = 184;
|
||||
public const JUNGLE_FENCE_GATE = 185;
|
||||
public const DARK_OAK_FENCE_GATE = 186;
|
||||
public const ACACIA_FENCE_GATE = 187;
|
||||
public const REPEATING_COMMAND_BLOCK = 188;
|
||||
public const CHAIN_COMMAND_BLOCK = 189;
|
||||
public const HARD_GLASS_PANE = 190;
|
||||
public const HARD_STAINED_GLASS_PANE = 191;
|
||||
public const CHEMICAL_HEAT = 192;
|
||||
public const SPRUCE_DOOR_BLOCK = 193;
|
||||
public const BIRCH_DOOR_BLOCK = 194;
|
||||
public const JUNGLE_DOOR_BLOCK = 195;
|
||||
public const ACACIA_DOOR_BLOCK = 196;
|
||||
public const DARK_OAK_DOOR_BLOCK = 197;
|
||||
public const GRASS_PATH = 198;
|
||||
public const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199;
|
||||
public const CHORUS_FLOWER = 200;
|
||||
public const PURPUR_BLOCK = 201;
|
||||
public const COLORED_TORCH_RG = 202;
|
||||
public const PURPUR_STAIRS = 203;
|
||||
public const COLORED_TORCH_BP = 204;
|
||||
public const UNDYED_SHULKER_BOX = 205;
|
||||
public const END_BRICKS = 206;
|
||||
public const FROSTED_ICE = 207;
|
||||
public const END_ROD = 208;
|
||||
public const END_GATEWAY = 209;
|
||||
|
||||
public const MAGMA = 213;
|
||||
public const NETHER_WART_BLOCK = 214;
|
||||
public const RED_NETHER_BRICK = 215;
|
||||
public const BONE_BLOCK = 216;
|
||||
|
||||
public const SHULKER_BOX = 218;
|
||||
public const PURPLE_GLAZED_TERRACOTTA = 219;
|
||||
public const WHITE_GLAZED_TERRACOTTA = 220;
|
||||
public const ORANGE_GLAZED_TERRACOTTA = 221;
|
||||
public const MAGENTA_GLAZED_TERRACOTTA = 222;
|
||||
public const LIGHT_BLUE_GLAZED_TERRACOTTA = 223;
|
||||
public const YELLOW_GLAZED_TERRACOTTA = 224;
|
||||
public const LIME_GLAZED_TERRACOTTA = 225;
|
||||
public const PINK_GLAZED_TERRACOTTA = 226;
|
||||
public const GRAY_GLAZED_TERRACOTTA = 227;
|
||||
public const SILVER_GLAZED_TERRACOTTA = 228;
|
||||
public const CYAN_GLAZED_TERRACOTTA = 229;
|
||||
|
||||
public const BLUE_GLAZED_TERRACOTTA = 231;
|
||||
public const BROWN_GLAZED_TERRACOTTA = 232;
|
||||
public const GREEN_GLAZED_TERRACOTTA = 233;
|
||||
public const RED_GLAZED_TERRACOTTA = 234;
|
||||
public const BLACK_GLAZED_TERRACOTTA = 235;
|
||||
public const CONCRETE = 236;
|
||||
public const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237;
|
||||
public const CHEMISTRY_TABLE = 238;
|
||||
public const UNDERWATER_TORCH = 239;
|
||||
public const CHORUS_PLANT = 240;
|
||||
public const STAINED_GLASS = 241;
|
||||
|
||||
public const PODZOL = 243;
|
||||
public const BEETROOT_BLOCK = 244;
|
||||
public const STONECUTTER = 245;
|
||||
public const GLOWINGOBSIDIAN = 246, GLOWING_OBSIDIAN = 246;
|
||||
public const NETHERREACTOR = 247, NETHER_REACTOR = 247;
|
||||
public const INFO_UPDATE = 248;
|
||||
public const INFO_UPDATE2 = 249;
|
||||
public const MOVINGBLOCK = 250, MOVING_BLOCK = 250;
|
||||
public const OBSERVER = 251;
|
||||
public const STRUCTURE_BLOCK = 252;
|
||||
public const HARD_GLASS = 253;
|
||||
public const HARD_STAINED_GLASS = 254;
|
||||
public const RESERVED6 = 255;
|
||||
|
||||
public const PRISMARINE_STAIRS = 257;
|
||||
public const DARK_PRISMARINE_STAIRS = 258;
|
||||
public const PRISMARINE_BRICKS_STAIRS = 259;
|
||||
public const STRIPPED_SPRUCE_LOG = 260;
|
||||
public const STRIPPED_BIRCH_LOG = 261;
|
||||
public const STRIPPED_JUNGLE_LOG = 262;
|
||||
public const STRIPPED_ACACIA_LOG = 263;
|
||||
public const STRIPPED_DARK_OAK_LOG = 264;
|
||||
public const STRIPPED_OAK_LOG = 265;
|
||||
public const BLUE_ICE = 266;
|
||||
public const ELEMENT_1 = 267;
|
||||
public const ELEMENT_2 = 268;
|
||||
public const ELEMENT_3 = 269;
|
||||
public const ELEMENT_4 = 270;
|
||||
public const ELEMENT_5 = 271;
|
||||
public const ELEMENT_6 = 272;
|
||||
public const ELEMENT_7 = 273;
|
||||
public const ELEMENT_8 = 274;
|
||||
public const ELEMENT_9 = 275;
|
||||
public const ELEMENT_10 = 276;
|
||||
public const ELEMENT_11 = 277;
|
||||
public const ELEMENT_12 = 278;
|
||||
public const ELEMENT_13 = 279;
|
||||
public const ELEMENT_14 = 280;
|
||||
public const ELEMENT_15 = 281;
|
||||
public const ELEMENT_16 = 282;
|
||||
public const ELEMENT_17 = 283;
|
||||
public const ELEMENT_18 = 284;
|
||||
public const ELEMENT_19 = 285;
|
||||
public const ELEMENT_20 = 286;
|
||||
public const ELEMENT_21 = 287;
|
||||
public const ELEMENT_22 = 288;
|
||||
public const ELEMENT_23 = 289;
|
||||
public const ELEMENT_24 = 290;
|
||||
public const ELEMENT_25 = 291;
|
||||
public const ELEMENT_26 = 292;
|
||||
public const ELEMENT_27 = 293;
|
||||
public const ELEMENT_28 = 294;
|
||||
public const ELEMENT_29 = 295;
|
||||
public const ELEMENT_30 = 296;
|
||||
public const ELEMENT_31 = 297;
|
||||
public const ELEMENT_32 = 298;
|
||||
public const ELEMENT_33 = 299;
|
||||
public const ELEMENT_34 = 300;
|
||||
public const ELEMENT_35 = 301;
|
||||
public const ELEMENT_36 = 302;
|
||||
public const ELEMENT_37 = 303;
|
||||
public const ELEMENT_38 = 304;
|
||||
public const ELEMENT_39 = 305;
|
||||
public const ELEMENT_40 = 306;
|
||||
public const ELEMENT_41 = 307;
|
||||
public const ELEMENT_42 = 308;
|
||||
public const ELEMENT_43 = 309;
|
||||
public const ELEMENT_44 = 310;
|
||||
public const ELEMENT_45 = 311;
|
||||
public const ELEMENT_46 = 312;
|
||||
public const ELEMENT_47 = 313;
|
||||
public const ELEMENT_48 = 314;
|
||||
public const ELEMENT_49 = 315;
|
||||
public const ELEMENT_50 = 316;
|
||||
public const ELEMENT_51 = 317;
|
||||
public const ELEMENT_52 = 318;
|
||||
public const ELEMENT_53 = 319;
|
||||
public const ELEMENT_54 = 320;
|
||||
public const ELEMENT_55 = 321;
|
||||
public const ELEMENT_56 = 322;
|
||||
public const ELEMENT_57 = 323;
|
||||
public const ELEMENT_58 = 324;
|
||||
public const ELEMENT_59 = 325;
|
||||
public const ELEMENT_60 = 326;
|
||||
public const ELEMENT_61 = 327;
|
||||
public const ELEMENT_62 = 328;
|
||||
public const ELEMENT_63 = 329;
|
||||
public const ELEMENT_64 = 330;
|
||||
public const ELEMENT_65 = 331;
|
||||
public const ELEMENT_66 = 332;
|
||||
public const ELEMENT_67 = 333;
|
||||
public const ELEMENT_68 = 334;
|
||||
public const ELEMENT_69 = 335;
|
||||
public const ELEMENT_70 = 336;
|
||||
public const ELEMENT_71 = 337;
|
||||
public const ELEMENT_72 = 338;
|
||||
public const ELEMENT_73 = 339;
|
||||
public const ELEMENT_74 = 340;
|
||||
public const ELEMENT_75 = 341;
|
||||
public const ELEMENT_76 = 342;
|
||||
public const ELEMENT_77 = 343;
|
||||
public const ELEMENT_78 = 344;
|
||||
public const ELEMENT_79 = 345;
|
||||
public const ELEMENT_80 = 346;
|
||||
public const ELEMENT_81 = 347;
|
||||
public const ELEMENT_82 = 348;
|
||||
public const ELEMENT_83 = 349;
|
||||
public const ELEMENT_84 = 350;
|
||||
public const ELEMENT_85 = 351;
|
||||
public const ELEMENT_86 = 352;
|
||||
public const ELEMENT_87 = 353;
|
||||
public const ELEMENT_88 = 354;
|
||||
public const ELEMENT_89 = 355;
|
||||
public const ELEMENT_90 = 356;
|
||||
public const ELEMENT_91 = 357;
|
||||
public const ELEMENT_92 = 358;
|
||||
public const ELEMENT_93 = 359;
|
||||
public const ELEMENT_94 = 360;
|
||||
public const ELEMENT_95 = 361;
|
||||
public const ELEMENT_96 = 362;
|
||||
public const ELEMENT_97 = 363;
|
||||
public const ELEMENT_98 = 364;
|
||||
public const ELEMENT_99 = 365;
|
||||
public const ELEMENT_100 = 366;
|
||||
public const ELEMENT_101 = 367;
|
||||
public const ELEMENT_102 = 368;
|
||||
public const ELEMENT_103 = 369;
|
||||
public const ELEMENT_104 = 370;
|
||||
public const ELEMENT_105 = 371;
|
||||
public const ELEMENT_106 = 372;
|
||||
public const ELEMENT_107 = 373;
|
||||
public const ELEMENT_108 = 374;
|
||||
public const ELEMENT_109 = 375;
|
||||
public const ELEMENT_110 = 376;
|
||||
public const ELEMENT_111 = 377;
|
||||
public const ELEMENT_112 = 378;
|
||||
public const ELEMENT_113 = 379;
|
||||
public const ELEMENT_114 = 380;
|
||||
public const ELEMENT_115 = 381;
|
||||
public const ELEMENT_116 = 382;
|
||||
public const ELEMENT_117 = 383;
|
||||
public const ELEMENT_118 = 384;
|
||||
public const SEAGRASS = 385;
|
||||
public const CORAL = 386;
|
||||
public const CORAL_BLOCK = 387;
|
||||
public const CORAL_FAN = 388;
|
||||
public const CORAL_FAN_DEAD = 389;
|
||||
public const CORAL_FAN_HANG = 390;
|
||||
public const CORAL_FAN_HANG2 = 391;
|
||||
public const CORAL_FAN_HANG3 = 392;
|
||||
public const KELP = 393;
|
||||
public const DRIED_KELP_BLOCK = 394;
|
||||
public const ACACIA_BUTTON = 395;
|
||||
public const BIRCH_BUTTON = 396;
|
||||
public const DARK_OAK_BUTTON = 397;
|
||||
public const JUNGLE_BUTTON = 398;
|
||||
public const SPRUCE_BUTTON = 399;
|
||||
public const ACACIA_TRAPDOOR = 400;
|
||||
public const BIRCH_TRAPDOOR = 401;
|
||||
public const DARK_OAK_TRAPDOOR = 402;
|
||||
public const JUNGLE_TRAPDOOR = 403;
|
||||
public const SPRUCE_TRAPDOOR = 404;
|
||||
public const ACACIA_PRESSURE_PLATE = 405;
|
||||
public const BIRCH_PRESSURE_PLATE = 406;
|
||||
public const DARK_OAK_PRESSURE_PLATE = 407;
|
||||
public const JUNGLE_PRESSURE_PLATE = 408;
|
||||
public const SPRUCE_PRESSURE_PLATE = 409;
|
||||
public const CARVED_PUMPKIN = 410;
|
||||
public const SEA_PICKLE = 411;
|
||||
public const CONDUIT = 412;
|
||||
|
||||
public const TURTLE_EGG = 414;
|
||||
public const BUBBLE_COLUMN = 415;
|
||||
public const BARRIER = 416;
|
||||
public const STONE_SLAB3 = 417;
|
||||
public const BAMBOO = 418;
|
||||
public const BAMBOO_SAPLING = 419;
|
||||
public const SCAFFOLDING = 420;
|
||||
public const STONE_SLAB4 = 421;
|
||||
public const DOUBLE_STONE_SLAB3 = 422;
|
||||
public const DOUBLE_STONE_SLAB4 = 423;
|
||||
public const GRANITE_STAIRS = 424;
|
||||
public const DIORITE_STAIRS = 425;
|
||||
public const ANDESITE_STAIRS = 426;
|
||||
public const POLISHED_GRANITE_STAIRS = 427;
|
||||
public const POLISHED_DIORITE_STAIRS = 428;
|
||||
public const POLISHED_ANDESITE_STAIRS = 429;
|
||||
public const MOSSY_STONE_BRICK_STAIRS = 430;
|
||||
public const SMOOTH_RED_SANDSTONE_STAIRS = 431;
|
||||
public const SMOOTH_SANDSTONE_STAIRS = 432;
|
||||
public const END_BRICK_STAIRS = 433;
|
||||
public const MOSSY_COBBLESTONE_STAIRS = 434;
|
||||
public const NORMAL_STONE_STAIRS = 435;
|
||||
public const SPRUCE_STANDING_SIGN = 436;
|
||||
public const SPRUCE_WALL_SIGN = 437;
|
||||
public const SMOOTH_STONE = 438;
|
||||
public const RED_NETHER_BRICK_STAIRS = 439;
|
||||
public const SMOOTH_QUARTZ_STAIRS = 440;
|
||||
public const BIRCH_STANDING_SIGN = 441;
|
||||
public const BIRCH_WALL_SIGN = 442;
|
||||
public const JUNGLE_STANDING_SIGN = 443;
|
||||
public const JUNGLE_WALL_SIGN = 444;
|
||||
public const ACACIA_STANDING_SIGN = 445;
|
||||
public const ACACIA_WALL_SIGN = 446;
|
||||
public const DARKOAK_STANDING_SIGN = 447;
|
||||
public const DARKOAK_WALL_SIGN = 448;
|
||||
public const LECTERN = 449;
|
||||
public const GRINDSTONE = 450;
|
||||
public const BLAST_FURNACE = 451;
|
||||
public const STONECUTTER_BLOCK = 452;
|
||||
public const SMOKER = 453;
|
||||
public const LIT_SMOKER = 454;
|
||||
public const CARTOGRAPHY_TABLE = 455;
|
||||
public const FLETCHING_TABLE = 456;
|
||||
public const SMITHING_TABLE = 457;
|
||||
public const BARREL = 458;
|
||||
public const LOOM = 459;
|
||||
|
||||
public const BELL = 461;
|
||||
public const SWEET_BERRY_BUSH = 462;
|
||||
public const LANTERN = 463;
|
||||
public const CAMPFIRE = 464;
|
||||
public const LAVA_CAULDRON = 465;
|
||||
public const JIGSAW = 466;
|
||||
public const WOOD = 467;
|
||||
public const COMPOSTER = 468;
|
||||
public const LIT_BLAST_FURNACE = 469;
|
||||
|
||||
}
|
303
src/block/BlockLegacyMetadata.php
Normal file
303
src/block/BlockLegacyMetadata.php
Normal file
@ -0,0 +1,303 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Constants for legacy metadata for various blocks.
|
||||
*/
|
||||
final class BlockLegacyMetadata{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const ANVIL_NORMAL = 0;
|
||||
public const ANVIL_SLIGHTLY_DAMAGED = 4;
|
||||
public const ANVIL_VERY_DAMAGED = 8;
|
||||
|
||||
public const BAMBOO_FLAG_THICK = 0x01;
|
||||
public const BAMBOO_FLAG_READY = 0x08;
|
||||
|
||||
public const BAMBOO_LEAF_SIZE_SHIFT = 1;
|
||||
public const BAMBOO_LEAF_SIZE_MASK = 0x03;
|
||||
|
||||
public const BAMBOO_SAPLING_FLAG_READY = 0x01;
|
||||
|
||||
public const BARREL_FLAG_OPEN = 0x08;
|
||||
|
||||
public const BED_FLAG_HEAD = 0x08;
|
||||
public const BED_FLAG_OCCUPIED = 0x04;
|
||||
|
||||
public const BEDROCK_FLAG_INFINIBURN = 0x01;
|
||||
|
||||
public const BELL_ATTACHMENT_FLOOR = 0;
|
||||
public const BELL_ATTACHMENT_CEILING = 1;
|
||||
public const BELL_ATTACHMENT_ONE_WALL = 2;
|
||||
public const BELL_ATTACHMENT_TWO_WALLS = 3;
|
||||
|
||||
public const BREWING_STAND_FLAG_EAST = 0x01;
|
||||
public const BREWING_STAND_FLAG_SOUTHWEST = 0x02;
|
||||
public const BREWING_STAND_FLAG_NORTHWEST = 0x04;
|
||||
|
||||
public const BUTTON_FLAG_POWERED = 0x08;
|
||||
|
||||
public const CHEMISTRY_COMPOUND_CREATOR = 0;
|
||||
public const CHEMISTRY_MATERIAL_REDUCER = 4;
|
||||
public const CHEMISTRY_ELEMENT_CONSTRUCTOR = 8;
|
||||
public const CHEMISTRY_LAB_TABLE = 12;
|
||||
|
||||
public const COLORED_TORCH_BP_BLUE = 0;
|
||||
public const COLORED_TORCH_BP_PURPLE = 8;
|
||||
public const COLORED_TORCH_RG_RED = 0;
|
||||
public const COLORED_TORCH_RG_GREEN = 8;
|
||||
|
||||
public const CORAL_BLOCK_FLAG_DEAD = 0x8;
|
||||
|
||||
public const CORAL_FAN_EAST_WEST = 0;
|
||||
public const CORAL_FAN_NORTH_SOUTH = 1;
|
||||
public const CORAL_FAN_TYPE_MASK = 0x7;
|
||||
|
||||
public const CORAL_FAN_HANG_FLAG_DEAD = 0x2;
|
||||
|
||||
public const CORAL_FAN_HANG_TUBE = 0;
|
||||
public const CORAL_FAN_HANG_BRAIN = 1;
|
||||
public const CORAL_FAN_HANG2_BUBBLE = 0;
|
||||
public const CORAL_FAN_HANG2_FIRE = 1;
|
||||
public const CORAL_FAN_HANG3_HORN = 0;
|
||||
public const CORAL_FAN_HANG_TYPE_MASK = 0x1;
|
||||
|
||||
public const CORAL_VARIANT_TUBE = 0;
|
||||
public const CORAL_VARIANT_BRAIN = 1;
|
||||
public const CORAL_VARIANT_BUBBLE = 2;
|
||||
public const CORAL_VARIANT_FIRE = 3;
|
||||
public const CORAL_VARIANT_HORN = 4;
|
||||
|
||||
public const DIRT_FLAG_COARSE = 0x1;
|
||||
|
||||
public const DOOR_FLAG_TOP = 0x08;
|
||||
public const DOOR_BOTTOM_FLAG_OPEN = 0x04;
|
||||
public const DOOR_TOP_FLAG_RIGHT = 0x01;
|
||||
public const DOOR_TOP_FLAG_POWERED = 0x02;
|
||||
|
||||
public const DOUBLE_PLANT_SUNFLOWER = 0;
|
||||
public const DOUBLE_PLANT_LILAC = 1;
|
||||
public const DOUBLE_PLANT_TALLGRASS = 2;
|
||||
public const DOUBLE_PLANT_LARGE_FERN = 3;
|
||||
public const DOUBLE_PLANT_ROSE_BUSH = 4;
|
||||
public const DOUBLE_PLANT_PEONY = 5;
|
||||
|
||||
public const DOUBLE_PLANT_FLAG_TOP = 0x08;
|
||||
|
||||
public const END_PORTAL_FRAME_FLAG_EYE = 0x04;
|
||||
|
||||
public const FENCE_GATE_FLAG_OPEN = 0x04;
|
||||
public const FENCE_GATE_FLAG_IN_WALL = 0x08;
|
||||
|
||||
public const FLOWER_POPPY = 0;
|
||||
public const FLOWER_BLUE_ORCHID = 1;
|
||||
public const FLOWER_ALLIUM = 2;
|
||||
public const FLOWER_AZURE_BLUET = 3;
|
||||
public const FLOWER_RED_TULIP = 4;
|
||||
public const FLOWER_ORANGE_TULIP = 5;
|
||||
public const FLOWER_WHITE_TULIP = 6;
|
||||
public const FLOWER_PINK_TULIP = 7;
|
||||
public const FLOWER_OXEYE_DAISY = 8;
|
||||
public const FLOWER_CORNFLOWER = 9;
|
||||
public const FLOWER_LILY_OF_THE_VALLEY = 10;
|
||||
|
||||
public const FLOWER_POT_FLAG_OCCUPIED = 0x01;
|
||||
|
||||
public const HOPPER_FLAG_POWERED = 0x08;
|
||||
|
||||
public const INFESTED_STONE = 0;
|
||||
public const INFESTED_COBBLESTONE = 1;
|
||||
public const INFESTED_STONE_BRICK = 2;
|
||||
public const INFESTED_STONE_BRICK_MOSSY = 3;
|
||||
public const INFESTED_STONE_BRICK_CRACKED = 4;
|
||||
public const INFESTED_STONE_BRICK_CHISELED = 5;
|
||||
|
||||
public const ITEM_FRAME_FLAG_HAS_MAP = 0x04;
|
||||
|
||||
public const LANTERN_FLAG_HANGING = 0x01;
|
||||
|
||||
public const LEAVES_FLAG_NO_DECAY = 0x04;
|
||||
public const LEAVES_FLAG_CHECK_DECAY = 0x08;
|
||||
|
||||
public const LECTERN_FLAG_POWERED = 0x04;
|
||||
|
||||
public const LEVER_FLAG_POWERED = 0x08;
|
||||
|
||||
public const LIQUID_FLAG_FALLING = 0x08;
|
||||
|
||||
public const MUSHROOM_BLOCK_ALL_PORES = 0;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER = 1;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTH_SIDE = 2;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER = 3;
|
||||
public const MUSHROOM_BLOCK_CAP_WEST_SIDE = 4;
|
||||
public const MUSHROOM_BLOCK_CAP_TOP_ONLY = 5;
|
||||
public const MUSHROOM_BLOCK_CAP_EAST_SIDE = 6;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER = 7;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTH_SIDE = 8;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER = 9;
|
||||
public const MUSHROOM_BLOCK_STEM = 10;
|
||||
//11, 12 and 13 appear the same as 0
|
||||
public const MUSHROOM_BLOCK_ALL_CAP = 14;
|
||||
public const MUSHROOM_BLOCK_ALL_STEM = 15;
|
||||
|
||||
public const NETHER_PORTAL_AXIS_X = 1;
|
||||
public const NETHER_PORTAL_AXIS_Z = 2;
|
||||
|
||||
public const NETHER_REACTOR_INACTIVE = 0;
|
||||
public const NETHER_REACTOR_ACTIVE = 1;
|
||||
public const NETHER_REACTOR_USED = 2;
|
||||
|
||||
public const PRESSURE_PLATE_FLAG_POWERED = 0x01;
|
||||
|
||||
public const PRISMARINE_NORMAL = 0;
|
||||
public const PRISMARINE_DARK = 1;
|
||||
public const PRISMARINE_BRICKS = 2;
|
||||
|
||||
public const PURPUR_NORMAL = 0;
|
||||
public const PURPUR_PILLAR = 2;
|
||||
|
||||
public const QUARTZ_NORMAL = 0;
|
||||
public const QUARTZ_CHISELED = 1;
|
||||
public const QUARTZ_PILLAR = 2;
|
||||
public const QUARTZ_SMOOTH = 3;
|
||||
|
||||
public const RAIL_STRAIGHT_NORTH_SOUTH = 0;
|
||||
public const RAIL_STRAIGHT_EAST_WEST = 1;
|
||||
public const RAIL_ASCENDING_EAST = 2;
|
||||
public const RAIL_ASCENDING_WEST = 3;
|
||||
public const RAIL_ASCENDING_NORTH = 4;
|
||||
public const RAIL_ASCENDING_SOUTH = 5;
|
||||
public const RAIL_CURVE_SOUTHEAST = 6;
|
||||
public const RAIL_CURVE_SOUTHWEST = 7;
|
||||
public const RAIL_CURVE_NORTHWEST = 8;
|
||||
public const RAIL_CURVE_NORTHEAST = 9;
|
||||
|
||||
public const REDSTONE_COMPARATOR_FLAG_SUBTRACT = 0x04;
|
||||
public const REDSTONE_COMPARATOR_FLAG_POWERED = 0x08;
|
||||
|
||||
public const REDSTONE_RAIL_FLAG_POWERED = 0x08;
|
||||
|
||||
public const SANDSTONE_NORMAL = 0;
|
||||
public const SANDSTONE_CHISELED = 1;
|
||||
public const SANDSTONE_CUT = 2;
|
||||
public const SANDSTONE_SMOOTH = 3;
|
||||
|
||||
public const SAPLING_FLAG_READY = 0x08;
|
||||
|
||||
public const SEA_PICKLE_FLAG_NOT_UNDERWATER = 0x04;
|
||||
|
||||
public const SKULL_FLAG_NO_DROPS = 0x08;
|
||||
|
||||
public const SLAB_FLAG_UPPER = 0x08;
|
||||
|
||||
public const SPONGE_FLAG_WET = 0x01;
|
||||
|
||||
public const STAIR_FLAG_UPSIDE_DOWN = 0x04;
|
||||
|
||||
public const STONE_NORMAL = 0;
|
||||
public const STONE_GRANITE = 1;
|
||||
public const STONE_POLISHED_GRANITE = 2;
|
||||
public const STONE_DIORITE = 3;
|
||||
public const STONE_POLISHED_DIORITE = 4;
|
||||
public const STONE_ANDESITE = 5;
|
||||
public const STONE_POLISHED_ANDESITE = 6;
|
||||
|
||||
public const STONE_BRICK_NORMAL = 0;
|
||||
public const STONE_BRICK_MOSSY = 1;
|
||||
public const STONE_BRICK_CRACKED = 2;
|
||||
public const STONE_BRICK_CHISELED = 3;
|
||||
|
||||
public const STONE_SLAB_SMOOTH_STONE = 0;
|
||||
public const STONE_SLAB_SANDSTONE = 1;
|
||||
public const STONE_SLAB_FAKE_WOODEN = 2;
|
||||
public const STONE_SLAB_COBBLESTONE = 3;
|
||||
public const STONE_SLAB_BRICK = 4;
|
||||
public const STONE_SLAB_STONE_BRICK = 5;
|
||||
public const STONE_SLAB_QUARTZ = 6;
|
||||
public const STONE_SLAB_NETHER_BRICK = 7;
|
||||
public const STONE_SLAB2_RED_SANDSTONE = 0;
|
||||
public const STONE_SLAB2_PURPUR = 1;
|
||||
public const STONE_SLAB2_PRISMARINE = 2;
|
||||
public const STONE_SLAB2_DARK_PRISMARINE = 3;
|
||||
public const STONE_SLAB2_PRISMARINE_BRICKS = 4;
|
||||
public const STONE_SLAB2_MOSSY_COBBLESTONE = 5;
|
||||
public const STONE_SLAB2_SMOOTH_SANDSTONE = 6;
|
||||
public const STONE_SLAB2_RED_NETHER_BRICK = 7;
|
||||
public const STONE_SLAB3_END_STONE_BRICK = 0;
|
||||
public const STONE_SLAB3_SMOOTH_RED_SANDSTONE = 1;
|
||||
public const STONE_SLAB3_POLISHED_ANDESITE = 2;
|
||||
public const STONE_SLAB3_ANDESITE = 3;
|
||||
public const STONE_SLAB3_DIORITE = 4;
|
||||
public const STONE_SLAB3_POLISHED_DIORITE = 5;
|
||||
public const STONE_SLAB3_GRANITE = 6;
|
||||
public const STONE_SLAB3_POLISHED_GRANITE = 7;
|
||||
public const STONE_SLAB4_MOSSY_STONE_BRICK = 0;
|
||||
public const STONE_SLAB4_SMOOTH_QUARTZ = 1;
|
||||
public const STONE_SLAB4_STONE = 2;
|
||||
public const STONE_SLAB4_CUT_SANDSTONE = 3;
|
||||
public const STONE_SLAB4_CUT_RED_SANDSTONE = 4;
|
||||
|
||||
public const TALLGRASS_NORMAL = 1;
|
||||
public const TALLGRASS_FERN = 2;
|
||||
|
||||
public const TNT_FLAG_UNSTABLE = 0x01;
|
||||
public const TNT_FLAG_UNDERWATER = 0x02;
|
||||
|
||||
public const TRAPDOOR_FLAG_UPPER = 0x04;
|
||||
public const TRAPDOOR_FLAG_OPEN = 0x08;
|
||||
|
||||
public const TRIPWIRE_FLAG_TRIGGERED = 0x01;
|
||||
public const TRIPWIRE_FLAG_SUSPENDED = 0x02;
|
||||
public const TRIPWIRE_FLAG_CONNECTED = 0x04;
|
||||
public const TRIPWIRE_FLAG_DISARMED = 0x08;
|
||||
|
||||
public const TRIPWIRE_HOOK_FLAG_CONNECTED = 0x04;
|
||||
public const TRIPWIRE_HOOK_FLAG_POWERED = 0x08;
|
||||
|
||||
public const VINE_FLAG_SOUTH = 0x01;
|
||||
public const VINE_FLAG_WEST = 0x02;
|
||||
public const VINE_FLAG_NORTH = 0x04;
|
||||
public const VINE_FLAG_EAST = 0x08;
|
||||
|
||||
public const WALL_COBBLESTONE = 0;
|
||||
public const WALL_MOSSY_COBBLESTONE = 1;
|
||||
public const WALL_GRANITE = 2;
|
||||
public const WALL_DIORITE = 3;
|
||||
public const WALL_ANDESITE = 4;
|
||||
public const WALL_SANDSTONE = 5;
|
||||
public const WALL_BRICK = 6;
|
||||
public const WALL_STONE_BRICK = 7;
|
||||
public const WALL_MOSSY_STONE_BRICK = 8;
|
||||
public const WALL_NETHER_BRICK = 9;
|
||||
public const WALL_END_STONE_BRICK = 10;
|
||||
public const WALL_PRISMARINE = 11;
|
||||
public const WALL_RED_SANDSTONE = 12;
|
||||
public const WALL_RED_NETHER_BRICK = 13;
|
||||
|
||||
public const WOOD_FLAG_STRIPPED = 0x8;
|
||||
}
|
@ -1,727 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Enum of all the block runtime IDs used by PocketMine-MP. These IDs are specific to PocketMine-MP and have no
|
||||
* relevance to any Minecraft vanilla things.
|
||||
*
|
||||
* WARNING: DO NOT STORE THESE IDS. They can and will change without warning.
|
||||
* They should ONLY be used to IDENTIFY blocks at runtime.
|
||||
*/
|
||||
final class BlockTypeIds{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const AIR = 10000;
|
||||
|
||||
public const ACACIA_BUTTON = 10001;
|
||||
public const ACACIA_DOOR = 10002;
|
||||
public const ACACIA_FENCE = 10003;
|
||||
public const ACACIA_FENCE_GATE = 10004;
|
||||
public const ACACIA_LEAVES = 10005;
|
||||
public const ACACIA_LOG = 10006;
|
||||
public const ACACIA_PLANKS = 10007;
|
||||
public const ACACIA_PRESSURE_PLATE = 10008;
|
||||
public const ACACIA_SAPLING = 10009;
|
||||
public const ACACIA_SIGN = 10010;
|
||||
public const ACACIA_SLAB = 10011;
|
||||
public const ACACIA_STAIRS = 10012;
|
||||
public const ACACIA_TRAPDOOR = 10013;
|
||||
public const ACACIA_WALL_SIGN = 10014;
|
||||
public const ACACIA_WOOD = 10015;
|
||||
public const ACTIVATOR_RAIL = 10016;
|
||||
public const ALL_SIDED_MUSHROOM_STEM = 10017;
|
||||
public const ALLIUM = 10018;
|
||||
public const ANDESITE = 10019;
|
||||
public const ANDESITE_SLAB = 10020;
|
||||
public const ANDESITE_STAIRS = 10021;
|
||||
public const ANDESITE_WALL = 10022;
|
||||
public const ANVIL = 10023;
|
||||
public const AZURE_BLUET = 10024;
|
||||
public const BAMBOO = 10025;
|
||||
public const BAMBOO_SAPLING = 10026;
|
||||
public const BANNER = 10027;
|
||||
public const BARREL = 10028;
|
||||
public const BARRIER = 10029;
|
||||
public const BEACON = 10030;
|
||||
public const BED = 10031;
|
||||
public const BEDROCK = 10032;
|
||||
public const BEETROOTS = 10033;
|
||||
public const BELL = 10034;
|
||||
public const BIRCH_BUTTON = 10035;
|
||||
public const BIRCH_DOOR = 10036;
|
||||
public const BIRCH_FENCE = 10037;
|
||||
public const BIRCH_FENCE_GATE = 10038;
|
||||
public const BIRCH_LEAVES = 10039;
|
||||
public const BIRCH_LOG = 10040;
|
||||
public const BIRCH_PLANKS = 10041;
|
||||
public const BIRCH_PRESSURE_PLATE = 10042;
|
||||
public const BIRCH_SAPLING = 10043;
|
||||
public const BIRCH_SIGN = 10044;
|
||||
public const BIRCH_SLAB = 10045;
|
||||
public const BIRCH_STAIRS = 10046;
|
||||
public const BIRCH_TRAPDOOR = 10047;
|
||||
public const BIRCH_WALL_SIGN = 10048;
|
||||
public const BIRCH_WOOD = 10049;
|
||||
|
||||
public const BLAST_FURNACE = 10051;
|
||||
|
||||
public const BLUE_ICE = 10053;
|
||||
public const BLUE_ORCHID = 10054;
|
||||
public const BLUE_TORCH = 10055;
|
||||
public const BONE_BLOCK = 10056;
|
||||
public const BOOKSHELF = 10057;
|
||||
public const BREWING_STAND = 10058;
|
||||
public const BRICK_SLAB = 10059;
|
||||
public const BRICK_STAIRS = 10060;
|
||||
public const BRICK_WALL = 10061;
|
||||
public const BRICKS = 10062;
|
||||
|
||||
public const BROWN_MUSHROOM = 10064;
|
||||
public const BROWN_MUSHROOM_BLOCK = 10065;
|
||||
public const CACTUS = 10066;
|
||||
public const CAKE = 10067;
|
||||
public const CARPET = 10068;
|
||||
public const CARROTS = 10069;
|
||||
public const CARVED_PUMPKIN = 10070;
|
||||
public const CHEMICAL_HEAT = 10071;
|
||||
public const CHEST = 10072;
|
||||
public const CHISELED_QUARTZ = 10073;
|
||||
public const CHISELED_RED_SANDSTONE = 10074;
|
||||
public const CHISELED_SANDSTONE = 10075;
|
||||
public const CHISELED_STONE_BRICKS = 10076;
|
||||
public const CLAY = 10077;
|
||||
public const COAL = 10078;
|
||||
public const COAL_ORE = 10079;
|
||||
public const COBBLESTONE = 10080;
|
||||
public const COBBLESTONE_SLAB = 10081;
|
||||
public const COBBLESTONE_STAIRS = 10082;
|
||||
public const COBBLESTONE_WALL = 10083;
|
||||
public const COBWEB = 10084;
|
||||
public const COCOA_POD = 10085;
|
||||
public const COMPOUND_CREATOR = 10086;
|
||||
public const CONCRETE = 10087;
|
||||
public const CONCRETE_POWDER = 10088;
|
||||
public const CORAL = 10089;
|
||||
public const CORAL_BLOCK = 10090;
|
||||
public const CORAL_FAN = 10091;
|
||||
public const CORNFLOWER = 10092;
|
||||
public const CRACKED_STONE_BRICKS = 10093;
|
||||
public const CRAFTING_TABLE = 10094;
|
||||
public const CUT_RED_SANDSTONE = 10095;
|
||||
public const CUT_RED_SANDSTONE_SLAB = 10096;
|
||||
public const CUT_SANDSTONE = 10097;
|
||||
public const CUT_SANDSTONE_SLAB = 10098;
|
||||
|
||||
public const DANDELION = 10100;
|
||||
public const DARK_OAK_BUTTON = 10101;
|
||||
public const DARK_OAK_DOOR = 10102;
|
||||
public const DARK_OAK_FENCE = 10103;
|
||||
public const DARK_OAK_FENCE_GATE = 10104;
|
||||
public const DARK_OAK_LEAVES = 10105;
|
||||
public const DARK_OAK_LOG = 10106;
|
||||
public const DARK_OAK_PLANKS = 10107;
|
||||
public const DARK_OAK_PRESSURE_PLATE = 10108;
|
||||
public const DARK_OAK_SAPLING = 10109;
|
||||
public const DARK_OAK_SIGN = 10110;
|
||||
public const DARK_OAK_SLAB = 10111;
|
||||
public const DARK_OAK_STAIRS = 10112;
|
||||
public const DARK_OAK_TRAPDOOR = 10113;
|
||||
public const DARK_OAK_WALL_SIGN = 10114;
|
||||
public const DARK_OAK_WOOD = 10115;
|
||||
public const DARK_PRISMARINE = 10116;
|
||||
public const DARK_PRISMARINE_SLAB = 10117;
|
||||
public const DARK_PRISMARINE_STAIRS = 10118;
|
||||
public const DAYLIGHT_SENSOR = 10119;
|
||||
public const DEAD_BUSH = 10120;
|
||||
public const DETECTOR_RAIL = 10121;
|
||||
public const DIAMOND = 10122;
|
||||
public const DIAMOND_ORE = 10123;
|
||||
public const DIORITE = 10124;
|
||||
public const DIORITE_SLAB = 10125;
|
||||
public const DIORITE_STAIRS = 10126;
|
||||
public const DIORITE_WALL = 10127;
|
||||
public const DIRT = 10128;
|
||||
public const DOUBLE_TALLGRASS = 10129;
|
||||
public const DRAGON_EGG = 10130;
|
||||
public const DRIED_KELP = 10131;
|
||||
public const DYED_SHULKER_BOX = 10132;
|
||||
public const ELEMENT_ACTINIUM = 10133;
|
||||
public const ELEMENT_ALUMINUM = 10134;
|
||||
public const ELEMENT_AMERICIUM = 10135;
|
||||
public const ELEMENT_ANTIMONY = 10136;
|
||||
public const ELEMENT_ARGON = 10137;
|
||||
public const ELEMENT_ARSENIC = 10138;
|
||||
public const ELEMENT_ASTATINE = 10139;
|
||||
public const ELEMENT_BARIUM = 10140;
|
||||
public const ELEMENT_BERKELIUM = 10141;
|
||||
public const ELEMENT_BERYLLIUM = 10142;
|
||||
public const ELEMENT_BISMUTH = 10143;
|
||||
public const ELEMENT_BOHRIUM = 10144;
|
||||
public const ELEMENT_BORON = 10145;
|
||||
public const ELEMENT_BROMINE = 10146;
|
||||
public const ELEMENT_CADMIUM = 10147;
|
||||
public const ELEMENT_CALCIUM = 10148;
|
||||
public const ELEMENT_CALIFORNIUM = 10149;
|
||||
public const ELEMENT_CARBON = 10150;
|
||||
public const ELEMENT_CERIUM = 10151;
|
||||
public const ELEMENT_CESIUM = 10152;
|
||||
public const ELEMENT_CHLORINE = 10153;
|
||||
public const ELEMENT_CHROMIUM = 10154;
|
||||
public const ELEMENT_COBALT = 10155;
|
||||
public const ELEMENT_CONSTRUCTOR = 10156;
|
||||
public const ELEMENT_COPERNICIUM = 10157;
|
||||
public const ELEMENT_COPPER = 10158;
|
||||
public const ELEMENT_CURIUM = 10159;
|
||||
public const ELEMENT_DARMSTADTIUM = 10160;
|
||||
public const ELEMENT_DUBNIUM = 10161;
|
||||
public const ELEMENT_DYSPROSIUM = 10162;
|
||||
public const ELEMENT_EINSTEINIUM = 10163;
|
||||
public const ELEMENT_ERBIUM = 10164;
|
||||
public const ELEMENT_EUROPIUM = 10165;
|
||||
public const ELEMENT_FERMIUM = 10166;
|
||||
public const ELEMENT_FLEROVIUM = 10167;
|
||||
public const ELEMENT_FLUORINE = 10168;
|
||||
public const ELEMENT_FRANCIUM = 10169;
|
||||
public const ELEMENT_GADOLINIUM = 10170;
|
||||
public const ELEMENT_GALLIUM = 10171;
|
||||
public const ELEMENT_GERMANIUM = 10172;
|
||||
public const ELEMENT_GOLD = 10173;
|
||||
public const ELEMENT_HAFNIUM = 10174;
|
||||
public const ELEMENT_HASSIUM = 10175;
|
||||
public const ELEMENT_HELIUM = 10176;
|
||||
public const ELEMENT_HOLMIUM = 10177;
|
||||
public const ELEMENT_HYDROGEN = 10178;
|
||||
public const ELEMENT_INDIUM = 10179;
|
||||
public const ELEMENT_IODINE = 10180;
|
||||
public const ELEMENT_IRIDIUM = 10181;
|
||||
public const ELEMENT_IRON = 10182;
|
||||
public const ELEMENT_KRYPTON = 10183;
|
||||
public const ELEMENT_LANTHANUM = 10184;
|
||||
public const ELEMENT_LAWRENCIUM = 10185;
|
||||
public const ELEMENT_LEAD = 10186;
|
||||
public const ELEMENT_LITHIUM = 10187;
|
||||
public const ELEMENT_LIVERMORIUM = 10188;
|
||||
public const ELEMENT_LUTETIUM = 10189;
|
||||
public const ELEMENT_MAGNESIUM = 10190;
|
||||
public const ELEMENT_MANGANESE = 10191;
|
||||
public const ELEMENT_MEITNERIUM = 10192;
|
||||
public const ELEMENT_MENDELEVIUM = 10193;
|
||||
public const ELEMENT_MERCURY = 10194;
|
||||
public const ELEMENT_MOLYBDENUM = 10195;
|
||||
public const ELEMENT_MOSCOVIUM = 10196;
|
||||
public const ELEMENT_NEODYMIUM = 10197;
|
||||
public const ELEMENT_NEON = 10198;
|
||||
public const ELEMENT_NEPTUNIUM = 10199;
|
||||
public const ELEMENT_NICKEL = 10200;
|
||||
public const ELEMENT_NIHONIUM = 10201;
|
||||
public const ELEMENT_NIOBIUM = 10202;
|
||||
public const ELEMENT_NITROGEN = 10203;
|
||||
public const ELEMENT_NOBELIUM = 10204;
|
||||
public const ELEMENT_OGANESSON = 10205;
|
||||
public const ELEMENT_OSMIUM = 10206;
|
||||
public const ELEMENT_OXYGEN = 10207;
|
||||
public const ELEMENT_PALLADIUM = 10208;
|
||||
public const ELEMENT_PHOSPHORUS = 10209;
|
||||
public const ELEMENT_PLATINUM = 10210;
|
||||
public const ELEMENT_PLUTONIUM = 10211;
|
||||
public const ELEMENT_POLONIUM = 10212;
|
||||
public const ELEMENT_POTASSIUM = 10213;
|
||||
public const ELEMENT_PRASEODYMIUM = 10214;
|
||||
public const ELEMENT_PROMETHIUM = 10215;
|
||||
public const ELEMENT_PROTACTINIUM = 10216;
|
||||
public const ELEMENT_RADIUM = 10217;
|
||||
public const ELEMENT_RADON = 10218;
|
||||
public const ELEMENT_RHENIUM = 10219;
|
||||
public const ELEMENT_RHODIUM = 10220;
|
||||
public const ELEMENT_ROENTGENIUM = 10221;
|
||||
public const ELEMENT_RUBIDIUM = 10222;
|
||||
public const ELEMENT_RUTHENIUM = 10223;
|
||||
public const ELEMENT_RUTHERFORDIUM = 10224;
|
||||
public const ELEMENT_SAMARIUM = 10225;
|
||||
public const ELEMENT_SCANDIUM = 10226;
|
||||
public const ELEMENT_SEABORGIUM = 10227;
|
||||
public const ELEMENT_SELENIUM = 10228;
|
||||
public const ELEMENT_SILICON = 10229;
|
||||
public const ELEMENT_SILVER = 10230;
|
||||
public const ELEMENT_SODIUM = 10231;
|
||||
public const ELEMENT_STRONTIUM = 10232;
|
||||
public const ELEMENT_SULFUR = 10233;
|
||||
public const ELEMENT_TANTALUM = 10234;
|
||||
public const ELEMENT_TECHNETIUM = 10235;
|
||||
public const ELEMENT_TELLURIUM = 10236;
|
||||
public const ELEMENT_TENNESSINE = 10237;
|
||||
public const ELEMENT_TERBIUM = 10238;
|
||||
public const ELEMENT_THALLIUM = 10239;
|
||||
public const ELEMENT_THORIUM = 10240;
|
||||
public const ELEMENT_THULIUM = 10241;
|
||||
public const ELEMENT_TIN = 10242;
|
||||
public const ELEMENT_TITANIUM = 10243;
|
||||
public const ELEMENT_TUNGSTEN = 10244;
|
||||
public const ELEMENT_URANIUM = 10245;
|
||||
public const ELEMENT_VANADIUM = 10246;
|
||||
public const ELEMENT_XENON = 10247;
|
||||
public const ELEMENT_YTTERBIUM = 10248;
|
||||
public const ELEMENT_YTTRIUM = 10249;
|
||||
public const ELEMENT_ZERO = 10250;
|
||||
public const ELEMENT_ZINC = 10251;
|
||||
public const ELEMENT_ZIRCONIUM = 10252;
|
||||
public const EMERALD = 10253;
|
||||
public const EMERALD_ORE = 10254;
|
||||
public const ENCHANTING_TABLE = 10255;
|
||||
public const END_PORTAL_FRAME = 10256;
|
||||
public const END_ROD = 10257;
|
||||
public const END_STONE = 10258;
|
||||
public const END_STONE_BRICK_SLAB = 10259;
|
||||
public const END_STONE_BRICK_STAIRS = 10260;
|
||||
public const END_STONE_BRICK_WALL = 10261;
|
||||
public const END_STONE_BRICKS = 10262;
|
||||
public const ENDER_CHEST = 10263;
|
||||
public const FAKE_WOODEN_SLAB = 10264;
|
||||
public const FARMLAND = 10265;
|
||||
public const FERN = 10266;
|
||||
public const FIRE = 10267;
|
||||
public const FLETCHING_TABLE = 10268;
|
||||
public const FLOWER_POT = 10269;
|
||||
public const FROSTED_ICE = 10270;
|
||||
public const FURNACE = 10271;
|
||||
public const GLASS = 10272;
|
||||
public const GLASS_PANE = 10273;
|
||||
public const GLOWING_OBSIDIAN = 10274;
|
||||
public const GLOWSTONE = 10275;
|
||||
public const GOLD = 10276;
|
||||
public const GOLD_ORE = 10277;
|
||||
public const GRANITE = 10278;
|
||||
public const GRANITE_SLAB = 10279;
|
||||
public const GRANITE_STAIRS = 10280;
|
||||
public const GRANITE_WALL = 10281;
|
||||
public const GRASS = 10282;
|
||||
public const GRASS_PATH = 10283;
|
||||
public const GRAVEL = 10284;
|
||||
|
||||
public const GREEN_TORCH = 10287;
|
||||
public const HARDENED_CLAY = 10288;
|
||||
public const HARDENED_GLASS = 10289;
|
||||
public const HARDENED_GLASS_PANE = 10290;
|
||||
public const HAY_BALE = 10291;
|
||||
public const HOPPER = 10292;
|
||||
public const ICE = 10293;
|
||||
public const INFESTED_CHISELED_STONE_BRICK = 10294;
|
||||
public const INFESTED_COBBLESTONE = 10295;
|
||||
public const INFESTED_CRACKED_STONE_BRICK = 10296;
|
||||
public const INFESTED_MOSSY_STONE_BRICK = 10297;
|
||||
public const INFESTED_STONE = 10298;
|
||||
public const INFESTED_STONE_BRICK = 10299;
|
||||
public const INFO_UPDATE = 10300;
|
||||
public const INFO_UPDATE2 = 10301;
|
||||
public const INVISIBLE_BEDROCK = 10302;
|
||||
public const IRON = 10303;
|
||||
public const IRON_BARS = 10304;
|
||||
public const IRON_DOOR = 10305;
|
||||
public const IRON_ORE = 10306;
|
||||
public const IRON_TRAPDOOR = 10307;
|
||||
public const ITEM_FRAME = 10308;
|
||||
public const JUKEBOX = 10309;
|
||||
public const JUNGLE_BUTTON = 10310;
|
||||
public const JUNGLE_DOOR = 10311;
|
||||
public const JUNGLE_FENCE = 10312;
|
||||
public const JUNGLE_FENCE_GATE = 10313;
|
||||
public const JUNGLE_LEAVES = 10314;
|
||||
public const JUNGLE_LOG = 10315;
|
||||
public const JUNGLE_PLANKS = 10316;
|
||||
public const JUNGLE_PRESSURE_PLATE = 10317;
|
||||
public const JUNGLE_SAPLING = 10318;
|
||||
public const JUNGLE_SIGN = 10319;
|
||||
public const JUNGLE_SLAB = 10320;
|
||||
public const JUNGLE_STAIRS = 10321;
|
||||
public const JUNGLE_TRAPDOOR = 10322;
|
||||
public const JUNGLE_WALL_SIGN = 10323;
|
||||
public const JUNGLE_WOOD = 10324;
|
||||
public const LAB_TABLE = 10325;
|
||||
public const LADDER = 10326;
|
||||
public const LANTERN = 10327;
|
||||
public const LAPIS_LAZULI = 10328;
|
||||
public const LAPIS_LAZULI_ORE = 10329;
|
||||
public const LARGE_FERN = 10330;
|
||||
public const LAVA = 10331;
|
||||
public const LECTERN = 10332;
|
||||
public const LEGACY_STONECUTTER = 10333;
|
||||
public const LEVER = 10334;
|
||||
|
||||
public const LILAC = 10337;
|
||||
public const LILY_OF_THE_VALLEY = 10338;
|
||||
public const LILY_PAD = 10339;
|
||||
|
||||
public const LIT_PUMPKIN = 10341;
|
||||
public const LOOM = 10342;
|
||||
|
||||
public const MAGMA = 10344;
|
||||
public const MATERIAL_REDUCER = 10345;
|
||||
public const MELON = 10346;
|
||||
public const MELON_STEM = 10347;
|
||||
public const MOB_HEAD = 10348;
|
||||
public const MONSTER_SPAWNER = 10349;
|
||||
public const MOSSY_COBBLESTONE = 10350;
|
||||
public const MOSSY_COBBLESTONE_SLAB = 10351;
|
||||
public const MOSSY_COBBLESTONE_STAIRS = 10352;
|
||||
public const MOSSY_COBBLESTONE_WALL = 10353;
|
||||
public const MOSSY_STONE_BRICK_SLAB = 10354;
|
||||
public const MOSSY_STONE_BRICK_STAIRS = 10355;
|
||||
public const MOSSY_STONE_BRICK_WALL = 10356;
|
||||
public const MOSSY_STONE_BRICKS = 10357;
|
||||
public const MUSHROOM_STEM = 10358;
|
||||
public const MYCELIUM = 10359;
|
||||
public const NETHER_BRICK_FENCE = 10360;
|
||||
public const NETHER_BRICK_SLAB = 10361;
|
||||
public const NETHER_BRICK_STAIRS = 10362;
|
||||
public const NETHER_BRICK_WALL = 10363;
|
||||
public const NETHER_BRICKS = 10364;
|
||||
public const NETHER_PORTAL = 10365;
|
||||
public const NETHER_QUARTZ_ORE = 10366;
|
||||
public const NETHER_REACTOR_CORE = 10367;
|
||||
public const NETHER_WART = 10368;
|
||||
public const NETHER_WART_BLOCK = 10369;
|
||||
public const NETHERRACK = 10370;
|
||||
public const NOTE_BLOCK = 10371;
|
||||
public const OAK_BUTTON = 10372;
|
||||
public const OAK_DOOR = 10373;
|
||||
public const OAK_FENCE = 10374;
|
||||
public const OAK_FENCE_GATE = 10375;
|
||||
public const OAK_LEAVES = 10376;
|
||||
public const OAK_LOG = 10377;
|
||||
public const OAK_PLANKS = 10378;
|
||||
public const OAK_PRESSURE_PLATE = 10379;
|
||||
public const OAK_SAPLING = 10380;
|
||||
public const OAK_SIGN = 10381;
|
||||
public const OAK_SLAB = 10382;
|
||||
public const OAK_STAIRS = 10383;
|
||||
public const OAK_TRAPDOOR = 10384;
|
||||
public const OAK_WALL_SIGN = 10385;
|
||||
public const OAK_WOOD = 10386;
|
||||
public const OBSIDIAN = 10387;
|
||||
|
||||
public const ORANGE_TULIP = 10389;
|
||||
public const OXEYE_DAISY = 10390;
|
||||
public const PACKED_ICE = 10391;
|
||||
public const PEONY = 10392;
|
||||
|
||||
public const PINK_TULIP = 10394;
|
||||
public const PODZOL = 10395;
|
||||
public const POLISHED_ANDESITE = 10396;
|
||||
public const POLISHED_ANDESITE_SLAB = 10397;
|
||||
public const POLISHED_ANDESITE_STAIRS = 10398;
|
||||
public const POLISHED_DIORITE = 10399;
|
||||
public const POLISHED_DIORITE_SLAB = 10400;
|
||||
public const POLISHED_DIORITE_STAIRS = 10401;
|
||||
public const POLISHED_GRANITE = 10402;
|
||||
public const POLISHED_GRANITE_SLAB = 10403;
|
||||
public const POLISHED_GRANITE_STAIRS = 10404;
|
||||
public const POPPY = 10405;
|
||||
public const POTATOES = 10406;
|
||||
public const POWERED_RAIL = 10407;
|
||||
public const PRISMARINE = 10408;
|
||||
public const PRISMARINE_BRICKS = 10409;
|
||||
public const PRISMARINE_BRICKS_SLAB = 10410;
|
||||
public const PRISMARINE_BRICKS_STAIRS = 10411;
|
||||
public const PRISMARINE_SLAB = 10412;
|
||||
public const PRISMARINE_STAIRS = 10413;
|
||||
public const PRISMARINE_WALL = 10414;
|
||||
public const PUMPKIN = 10415;
|
||||
public const PUMPKIN_STEM = 10416;
|
||||
|
||||
public const PURPLE_TORCH = 10418;
|
||||
public const PURPUR = 10419;
|
||||
public const PURPUR_PILLAR = 10420;
|
||||
public const PURPUR_SLAB = 10421;
|
||||
public const PURPUR_STAIRS = 10422;
|
||||
public const QUARTZ = 10423;
|
||||
public const QUARTZ_PILLAR = 10424;
|
||||
public const QUARTZ_SLAB = 10425;
|
||||
public const QUARTZ_STAIRS = 10426;
|
||||
public const RAIL = 10427;
|
||||
|
||||
public const RED_MUSHROOM = 10429;
|
||||
public const RED_MUSHROOM_BLOCK = 10430;
|
||||
public const RED_NETHER_BRICK_SLAB = 10431;
|
||||
public const RED_NETHER_BRICK_STAIRS = 10432;
|
||||
public const RED_NETHER_BRICK_WALL = 10433;
|
||||
public const RED_NETHER_BRICKS = 10434;
|
||||
public const RED_SAND = 10435;
|
||||
public const RED_SANDSTONE = 10436;
|
||||
public const RED_SANDSTONE_SLAB = 10437;
|
||||
public const RED_SANDSTONE_STAIRS = 10438;
|
||||
public const RED_SANDSTONE_WALL = 10439;
|
||||
public const RED_TORCH = 10440;
|
||||
public const RED_TULIP = 10441;
|
||||
public const REDSTONE = 10442;
|
||||
public const REDSTONE_COMPARATOR = 10443;
|
||||
public const REDSTONE_LAMP = 10444;
|
||||
public const REDSTONE_ORE = 10445;
|
||||
public const REDSTONE_REPEATER = 10446;
|
||||
public const REDSTONE_TORCH = 10447;
|
||||
public const REDSTONE_WIRE = 10448;
|
||||
public const RESERVED6 = 10449;
|
||||
public const ROSE_BUSH = 10450;
|
||||
public const SAND = 10451;
|
||||
public const SANDSTONE = 10452;
|
||||
public const SANDSTONE_SLAB = 10453;
|
||||
public const SANDSTONE_STAIRS = 10454;
|
||||
public const SANDSTONE_WALL = 10455;
|
||||
public const SEA_LANTERN = 10456;
|
||||
public const SEA_PICKLE = 10457;
|
||||
public const SHULKER_BOX = 10458;
|
||||
public const SLIME = 10459;
|
||||
public const SMOKER = 10460;
|
||||
public const SMOOTH_QUARTZ = 10461;
|
||||
public const SMOOTH_QUARTZ_SLAB = 10462;
|
||||
public const SMOOTH_QUARTZ_STAIRS = 10463;
|
||||
public const SMOOTH_RED_SANDSTONE = 10464;
|
||||
public const SMOOTH_RED_SANDSTONE_SLAB = 10465;
|
||||
public const SMOOTH_RED_SANDSTONE_STAIRS = 10466;
|
||||
public const SMOOTH_SANDSTONE = 10467;
|
||||
public const SMOOTH_SANDSTONE_SLAB = 10468;
|
||||
public const SMOOTH_SANDSTONE_STAIRS = 10469;
|
||||
public const SMOOTH_STONE = 10470;
|
||||
public const SMOOTH_STONE_SLAB = 10471;
|
||||
public const SNOW = 10472;
|
||||
public const SNOW_LAYER = 10473;
|
||||
public const SOUL_SAND = 10474;
|
||||
public const SPONGE = 10475;
|
||||
public const SPRUCE_BUTTON = 10476;
|
||||
public const SPRUCE_DOOR = 10477;
|
||||
public const SPRUCE_FENCE = 10478;
|
||||
public const SPRUCE_FENCE_GATE = 10479;
|
||||
public const SPRUCE_LEAVES = 10480;
|
||||
public const SPRUCE_LOG = 10481;
|
||||
public const SPRUCE_PLANKS = 10482;
|
||||
public const SPRUCE_PRESSURE_PLATE = 10483;
|
||||
public const SPRUCE_SAPLING = 10484;
|
||||
public const SPRUCE_SIGN = 10485;
|
||||
public const SPRUCE_SLAB = 10486;
|
||||
public const SPRUCE_STAIRS = 10487;
|
||||
public const SPRUCE_TRAPDOOR = 10488;
|
||||
public const SPRUCE_WALL_SIGN = 10489;
|
||||
public const SPRUCE_WOOD = 10490;
|
||||
public const STAINED_CLAY = 10491;
|
||||
public const STAINED_GLASS = 10492;
|
||||
public const STAINED_GLASS_PANE = 10493;
|
||||
public const STAINED_HARDENED_GLASS = 10494;
|
||||
public const STAINED_HARDENED_GLASS_PANE = 10495;
|
||||
public const STONE = 10496;
|
||||
public const STONE_BRICK_SLAB = 10497;
|
||||
public const STONE_BRICK_STAIRS = 10498;
|
||||
public const STONE_BRICK_WALL = 10499;
|
||||
public const STONE_BRICKS = 10500;
|
||||
public const STONE_BUTTON = 10501;
|
||||
public const STONE_PRESSURE_PLATE = 10502;
|
||||
public const STONE_SLAB = 10503;
|
||||
public const STONE_STAIRS = 10504;
|
||||
public const STONECUTTER = 10505;
|
||||
|
||||
public const SUGARCANE = 10518;
|
||||
public const SUNFLOWER = 10519;
|
||||
public const SWEET_BERRY_BUSH = 10520;
|
||||
public const TALL_GRASS = 10521;
|
||||
public const TNT = 10522;
|
||||
public const TORCH = 10523;
|
||||
public const TRAPPED_CHEST = 10524;
|
||||
public const TRIPWIRE = 10525;
|
||||
public const TRIPWIRE_HOOK = 10526;
|
||||
public const UNDERWATER_TORCH = 10527;
|
||||
public const VINES = 10528;
|
||||
public const WALL_BANNER = 10529;
|
||||
public const WALL_CORAL_FAN = 10530;
|
||||
public const WATER = 10531;
|
||||
public const WEIGHTED_PRESSURE_PLATE_HEAVY = 10532;
|
||||
public const WEIGHTED_PRESSURE_PLATE_LIGHT = 10533;
|
||||
public const WHEAT = 10534;
|
||||
|
||||
public const WHITE_TULIP = 10536;
|
||||
public const WOOL = 10537;
|
||||
|
||||
public const GLAZED_TERRACOTTA = 10539;
|
||||
public const AMETHYST = 10540;
|
||||
public const ANCIENT_DEBRIS = 10541;
|
||||
public const BASALT = 10542;
|
||||
public const POLISHED_BASALT = 10543;
|
||||
public const SMOOTH_BASALT = 10544;
|
||||
public const BLACKSTONE = 10545;
|
||||
public const BLACKSTONE_SLAB = 10546;
|
||||
public const BLACKSTONE_STAIRS = 10547;
|
||||
public const BLACKSTONE_WALL = 10548;
|
||||
public const POLISHED_BLACKSTONE = 10549;
|
||||
public const POLISHED_BLACKSTONE_BUTTON = 10550;
|
||||
public const POLISHED_BLACKSTONE_PRESSURE_PLATE = 10551;
|
||||
public const POLISHED_BLACKSTONE_SLAB = 10552;
|
||||
public const POLISHED_BLACKSTONE_STAIRS = 10553;
|
||||
public const POLISHED_BLACKSTONE_WALL = 10554;
|
||||
public const CHISELED_POLISHED_BLACKSTONE = 10555;
|
||||
public const POLISHED_BLACKSTONE_BRICKS = 10556;
|
||||
public const POLISHED_BLACKSTONE_BRICK_SLAB = 10557;
|
||||
public const POLISHED_BLACKSTONE_BRICK_STAIRS = 10558;
|
||||
public const POLISHED_BLACKSTONE_BRICK_WALL = 10559;
|
||||
public const CRACKED_POLISHED_BLACKSTONE_BRICKS = 10560;
|
||||
public const LIGHT = 10561;
|
||||
public const RAW_COPPER = 10562;
|
||||
public const RAW_GOLD = 10563;
|
||||
public const RAW_IRON = 10564;
|
||||
public const CALCITE = 10565;
|
||||
public const DEEPSLATE = 10566;
|
||||
public const DEEPSLATE_BRICKS = 10567;
|
||||
public const DEEPSLATE_BRICK_SLAB = 10568;
|
||||
public const DEEPSLATE_BRICK_STAIRS = 10569;
|
||||
public const DEEPSLATE_BRICK_WALL = 10570;
|
||||
public const CRACKED_DEEPSLATE_BRICKS = 10571;
|
||||
public const DEEPSLATE_TILES = 10572;
|
||||
public const DEEPSLATE_TILE_SLAB = 10573;
|
||||
public const DEEPSLATE_TILE_STAIRS = 10574;
|
||||
public const DEEPSLATE_TILE_WALL = 10575;
|
||||
public const CRACKED_DEEPSLATE_TILES = 10576;
|
||||
public const COBBLED_DEEPSLATE = 10577;
|
||||
public const COBBLED_DEEPSLATE_SLAB = 10578;
|
||||
public const COBBLED_DEEPSLATE_STAIRS = 10579;
|
||||
public const COBBLED_DEEPSLATE_WALL = 10580;
|
||||
public const POLISHED_DEEPSLATE = 10581;
|
||||
public const POLISHED_DEEPSLATE_SLAB = 10582;
|
||||
public const POLISHED_DEEPSLATE_STAIRS = 10583;
|
||||
public const POLISHED_DEEPSLATE_WALL = 10584;
|
||||
public const QUARTZ_BRICKS = 10585;
|
||||
public const CHISELED_DEEPSLATE = 10586;
|
||||
public const CHISELED_NETHER_BRICKS = 10587;
|
||||
public const CRACKED_NETHER_BRICKS = 10588;
|
||||
public const TUFF = 10589;
|
||||
public const SOUL_TORCH = 10590;
|
||||
public const SOUL_LANTERN = 10591;
|
||||
public const SOUL_SOIL = 10592;
|
||||
public const SOUL_FIRE = 10593;
|
||||
public const SHROOMLIGHT = 10594;
|
||||
public const MANGROVE_PLANKS = 10595;
|
||||
public const CRIMSON_PLANKS = 10596;
|
||||
public const WARPED_PLANKS = 10597;
|
||||
public const MANGROVE_FENCE = 10598;
|
||||
public const CRIMSON_FENCE = 10599;
|
||||
public const WARPED_FENCE = 10600;
|
||||
public const MANGROVE_SLAB = 10601;
|
||||
public const CRIMSON_SLAB = 10602;
|
||||
public const WARPED_SLAB = 10603;
|
||||
public const MANGROVE_LOG = 10604;
|
||||
public const CRIMSON_STEM = 10605;
|
||||
public const WARPED_STEM = 10606;
|
||||
public const MANGROVE_WOOD = 10607;
|
||||
public const CRIMSON_HYPHAE = 10608;
|
||||
public const WARPED_HYPHAE = 10609;
|
||||
public const MANGROVE_TRAPDOOR = 10610;
|
||||
public const CRIMSON_TRAPDOOR = 10611;
|
||||
public const WARPED_TRAPDOOR = 10612;
|
||||
public const MANGROVE_BUTTON = 10613;
|
||||
public const CRIMSON_BUTTON = 10614;
|
||||
public const WARPED_BUTTON = 10615;
|
||||
public const MANGROVE_PRESSURE_PLATE = 10616;
|
||||
public const CRIMSON_PRESSURE_PLATE = 10617;
|
||||
public const WARPED_PRESSURE_PLATE = 10618;
|
||||
public const MANGROVE_DOOR = 10619;
|
||||
public const CRIMSON_DOOR = 10620;
|
||||
public const WARPED_DOOR = 10621;
|
||||
public const MANGROVE_FENCE_GATE = 10622;
|
||||
public const CRIMSON_FENCE_GATE = 10623;
|
||||
public const WARPED_FENCE_GATE = 10624;
|
||||
public const MANGROVE_STAIRS = 10625;
|
||||
public const CRIMSON_STAIRS = 10626;
|
||||
public const WARPED_STAIRS = 10627;
|
||||
public const MANGROVE_SIGN = 10628;
|
||||
public const CRIMSON_SIGN = 10629;
|
||||
public const WARPED_SIGN = 10630;
|
||||
public const MANGROVE_WALL_SIGN = 10631;
|
||||
public const CRIMSON_WALL_SIGN = 10632;
|
||||
public const WARPED_WALL_SIGN = 10633;
|
||||
public const TINTED_GLASS = 10634;
|
||||
public const HONEYCOMB = 10635;
|
||||
public const DEEPSLATE_COAL_ORE = 10636;
|
||||
public const DEEPSLATE_DIAMOND_ORE = 10637;
|
||||
public const DEEPSLATE_EMERALD_ORE = 10638;
|
||||
public const DEEPSLATE_LAPIS_LAZULI_ORE = 10639;
|
||||
public const DEEPSLATE_REDSTONE_ORE = 10640;
|
||||
public const DEEPSLATE_IRON_ORE = 10641;
|
||||
public const DEEPSLATE_GOLD_ORE = 10642;
|
||||
public const DEEPSLATE_COPPER_ORE = 10643;
|
||||
public const COPPER_ORE = 10644;
|
||||
public const NETHER_GOLD_ORE = 10645;
|
||||
public const MUD = 10646;
|
||||
public const MUD_BRICKS = 10647;
|
||||
public const MUD_BRICK_SLAB = 10648;
|
||||
public const MUD_BRICK_STAIRS = 10649;
|
||||
public const MUD_BRICK_WALL = 10650;
|
||||
public const PACKED_MUD = 10651;
|
||||
public const WARPED_WART_BLOCK = 10652;
|
||||
public const CRYING_OBSIDIAN = 10653;
|
||||
public const GILDED_BLACKSTONE = 10654;
|
||||
public const LIGHTNING_ROD = 10655;
|
||||
public const COPPER = 10656;
|
||||
public const CUT_COPPER = 10657;
|
||||
public const CUT_COPPER_SLAB = 10658;
|
||||
public const CUT_COPPER_STAIRS = 10659;
|
||||
public const CANDLE = 10660;
|
||||
public const DYED_CANDLE = 10661;
|
||||
public const CAKE_WITH_CANDLE = 10662;
|
||||
public const CAKE_WITH_DYED_CANDLE = 10663;
|
||||
public const WITHER_ROSE = 10664;
|
||||
public const HANGING_ROOTS = 10665;
|
||||
public const CARTOGRAPHY_TABLE = 10666;
|
||||
public const SMITHING_TABLE = 10667;
|
||||
public const NETHERITE = 10668;
|
||||
public const SPORE_BLOSSOM = 10669;
|
||||
public const CAULDRON = 10670;
|
||||
public const WATER_CAULDRON = 10671;
|
||||
public const LAVA_CAULDRON = 10672;
|
||||
public const POTION_CAULDRON = 10673;
|
||||
public const POWDER_SNOW_CAULDRON = 10674;
|
||||
public const CHORUS_FLOWER = 10675;
|
||||
public const CHORUS_PLANT = 10676;
|
||||
public const MANGROVE_ROOTS = 10677;
|
||||
public const MUDDY_MANGROVE_ROOTS = 10678;
|
||||
public const FROGLIGHT = 10679;
|
||||
public const TWISTING_VINES = 10680;
|
||||
public const WEEPING_VINES = 10681;
|
||||
public const CHAIN = 10682;
|
||||
public const SCULK = 10683;
|
||||
public const GLOWING_ITEM_FRAME = 10684;
|
||||
public const MANGROVE_LEAVES = 10685;
|
||||
public const AZALEA_LEAVES = 10686;
|
||||
public const FLOWERING_AZALEA_LEAVES = 10687;
|
||||
public const REINFORCED_DEEPSLATE = 10688;
|
||||
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10689;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
/**
|
||||
* Returns a new runtime block type ID, e.g. for use by a custom block.
|
||||
*/
|
||||
public static function newId() : int{
|
||||
return self::$nextDynamicId++;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use function array_fill_keys;
|
||||
use function array_keys;
|
||||
|
||||
final class BlockTypeInfo{
|
||||
/**
|
||||
* @var true[]
|
||||
* @phpstan-var array<string, true>
|
||||
*/
|
||||
private array $typeTags;
|
||||
|
||||
/**
|
||||
* @param string[] $typeTags
|
||||
*/
|
||||
public function __construct(
|
||||
private BlockBreakInfo $breakInfo,
|
||||
array $typeTags = []
|
||||
){
|
||||
$this->typeTags = array_fill_keys($typeTags, true);
|
||||
}
|
||||
|
||||
public function getBreakInfo() : BlockBreakInfo{ return $this->breakInfo; }
|
||||
|
||||
/** @return string[] */
|
||||
public function getTypeTags() : array{ return array_keys($this->typeTags); }
|
||||
|
||||
public function hasTypeTag(string $tag) : bool{ return isset($this->typeTags[$tag]); }
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
final class BlockTypeTags{
|
||||
private const PREFIX = "pocketmine:";
|
||||
|
||||
public const DIRT = self::PREFIX . "dirt";
|
||||
public const MUD = self::PREFIX . "mud";
|
||||
public const SAND = self::PREFIX . "sand";
|
||||
public const POTTABLE_PLANTS = self::PREFIX . "pottable";
|
||||
public const FIRE = self::PREFIX . "fire";
|
||||
}
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationTrait;
|
||||
use pocketmine\block\utils\PillarRotationInMetadataTrait;
|
||||
|
||||
class BoneBlock extends Opaque{
|
||||
use PillarRotationTrait;
|
||||
use PillarRotationInMetadataTrait;
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\tile\BrewingStand as TileBrewingStand;
|
||||
use pocketmine\block\utils\BrewingStandSlot;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -43,8 +42,33 @@ class BrewingStand extends Transparent{
|
||||
*/
|
||||
protected array $slots = [];
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->brewingStandSlots($this->slots);
|
||||
protected function writeStateToMeta() : int{
|
||||
$flags = 0;
|
||||
foreach([
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(),
|
||||
] as $flag => $slot){
|
||||
$flags |= (array_key_exists($slot->id(), $this->slots) ? $flag : 0);
|
||||
}
|
||||
return $flags;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->slots = [];
|
||||
foreach([
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(),
|
||||
] as $flag => $slot){
|
||||
if(($stateMeta & $flag) !== 0){
|
||||
$this->slots[$slot->id()] = $slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
@ -94,7 +118,7 @@ class BrewingStand extends Transparent{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$stand = $this->position->getWorld()->getTile($this->position);
|
||||
if($stand instanceof TileBrewingStand && $stand->canOpenWith($item->getCustomName())){
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -38,9 +38,18 @@ abstract class Button extends Flowable{
|
||||
|
||||
protected bool $pressed = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->facing($this->facing);
|
||||
$w->bool($this->pressed);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeFacing($this->facing) | ($this->pressed ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
//TODO: in PC it's (6 - facing) for every meta except 0 (down)
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07);
|
||||
$this->pressed = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function isPressed() : bool{ return $this->pressed; }
|
||||
@ -61,7 +70,7 @@ abstract class Button extends Flowable{
|
||||
|
||||
abstract protected function getActivationTime() : int;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->pressed){
|
||||
$this->pressed = true;
|
||||
$world = $this->position->getWorld();
|
||||
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
@ -41,8 +41,16 @@ class Cactus extends Transparent{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, self::MAX_AGE, $this->age);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -78,13 +86,10 @@ class Cactus extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSameType($this) || $block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if($down->getId() !== BlockLegacyIds::SAND && !$down->isSameType($this)){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
@ -110,7 +115,7 @@ class Cactus extends Transparent{
|
||||
break;
|
||||
}
|
||||
$b = $world->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z);
|
||||
if($b->getTypeId() === BlockTypeIds::AIR){
|
||||
if($b->getId() === BlockLegacyIds::AIR){
|
||||
$ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS());
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
@ -131,7 +136,8 @@ class Cactus 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))){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() === BlockLegacyIds::SAND || $down->isSameType($this)){
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
if($this->getSide($side)->isSolid()){
|
||||
return false;
|
||||
|
@ -23,21 +23,33 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\FoodSource;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemBlock;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Cake extends BaseCake{
|
||||
class Cake extends Transparent implements FoodSource{
|
||||
public const MAX_BITES = 6;
|
||||
|
||||
protected int $bites = 0;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_BITES, $this->bites);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->bites;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->bites = BlockDataSerializer::readBoundedInt("bites", $stateMeta, 0, self::MAX_BITES);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,6 +64,10 @@ class Cake extends BaseCake{
|
||||
];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function getBites() : int{ return $this->bites; }
|
||||
|
||||
/** @return $this */
|
||||
@ -63,27 +79,49 @@ class Cake extends BaseCake{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof ItemBlock){
|
||||
$block = $item->getBlock();
|
||||
$resultBlock = null;
|
||||
if($block->getTypeId() === BlockTypeIds::CANDLE){
|
||||
$resultBlock = VanillaBlocks::CAKE_WITH_CANDLE();
|
||||
}elseif($block instanceof DyedCandle){
|
||||
$resultBlock = VanillaBlocks::CAKE_WITH_DYED_CANDLE()->setColor($block->getColor());
|
||||
}
|
||||
|
||||
if($resultBlock !== null){
|
||||
$this->position->getWorld()->setBlock($this->position, $resultBlock);
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() !== BlockLegacyIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return parent::onInteract($item, $face, $clickVector, $player, $returnedItems);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getResidue() : Block{
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
return $player->consumeObject($this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFoodRestore() : int{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getSaturationRestore() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Block
|
||||
*/
|
||||
public function getResidue(){
|
||||
$clone = clone $this;
|
||||
$clone->bites++;
|
||||
if($clone->bites > self::MAX_BITES){
|
||||
@ -91,4 +129,15 @@ class Cake extends BaseCake{
|
||||
}
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EffectInstance[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $this->getResidue());
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CandleTrait;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
class CakeWithCandle extends BaseCake{
|
||||
use CandleTrait {
|
||||
onInteract as onInteractCandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
AxisAlignedBB::one()
|
||||
->contract(1 / 16, 0, 1 / 16)
|
||||
->trim(Facing::UP, 0.5) //TODO: not sure if the candle affects height
|
||||
];
|
||||
}
|
||||
|
||||
public function getCandle() : Candle{
|
||||
return VanillaBlocks::CANDLE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($this->onInteractCandle($item, $face, $clickVector, $player, $returnedItems)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::onInteract($item, $face, $clickVector, $player, $returnedItems);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [$this->getCandle()->asItem()];
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaBlocks::CAKE()->getPickedItem($addUserData);
|
||||
}
|
||||
|
||||
public function getResidue() : Block{
|
||||
return VanillaBlocks::CAKE()->setBites(1);
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
parent::onConsume($consumer);
|
||||
$this->position->getWorld()->dropItem($this->position->add(0.5, 0.5, 0.5), $this->getCandle()->asItem());
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class CakeWithDyedCandle extends CakeWithCandle{
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function getCandle() : Candle{
|
||||
return VanillaBlocks::DYED_CANDLE()->setColor($this->color);
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CandleTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Candle extends Transparent{
|
||||
use CandleTrait {
|
||||
describeState as encodeLitState;
|
||||
getLightLevel as getBaseLightLevel;
|
||||
}
|
||||
|
||||
public const MIN_COUNT = 1;
|
||||
public const MAX_COUNT = 4;
|
||||
|
||||
private int $count = self::MIN_COUNT;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$this->encodeLitState($w);
|
||||
$w->boundedInt(2, self::MIN_COUNT, self::MAX_COUNT, $this->count);
|
||||
}
|
||||
|
||||
public function getCount() : int{ return $this->count; }
|
||||
|
||||
/** @return $this */
|
||||
public function setCount(int $count) : self{
|
||||
if($count < self::MIN_COUNT || $count > self::MAX_COUNT){
|
||||
throw new \InvalidArgumentException("Count must be in range " . self::MIN_COUNT . " ... " . self::MAX_COUNT);
|
||||
}
|
||||
$this->count = $count;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return $this->getBaseLightLevel() * $this->count;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
(match($this->count){
|
||||
1 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 7 / 16)
|
||||
->squash(Axis::Z, 7 / 16),
|
||||
2 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 5 / 16)
|
||||
->trim(Facing::NORTH, 7 / 16) //0.3 thick on the Z axis
|
||||
->trim(Facing::SOUTH, 6 / 16),
|
||||
3 => AxisAlignedBB::one()
|
||||
->trim(Facing::WEST, 5 / 16)
|
||||
->trim(Facing::EAST, 6 / 16)
|
||||
->trim(Facing::NORTH, 6 / 16)
|
||||
->trim(Facing::SOUTH, 5 / 16),
|
||||
4 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 5 / 16)
|
||||
->trim(Facing::NORTH, 5 / 16)
|
||||
->trim(Facing::SOUTH, 6 / 16),
|
||||
default => throw new AssumptionFailedError("Unreachable")
|
||||
})->trim(Facing::UP, 10 / 16)
|
||||
];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function getCandleIfCompatibleType(Block $block) : ?Candle{
|
||||
return $block instanceof Candle && $block->isSameType($this) ? $block : null;
|
||||
}
|
||||
|
||||
public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{
|
||||
$candle = $this->getCandleIfCompatibleType($blockReplace);
|
||||
return $candle !== null ? $candle->count < self::MAX_COUNT : parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock);
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $blockReplace->getSide(Facing::DOWN);
|
||||
if(!$down->getSupportType(Facing::UP)->hasCenterSupport()){
|
||||
return false;
|
||||
}
|
||||
$existing = $this->getCandleIfCompatibleType($blockReplace);
|
||||
if($existing !== null){
|
||||
if($existing->count >= self::MAX_COUNT){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->count = $existing->count + 1;
|
||||
$this->lit = $existing->lit;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [$this->asItem()->setCount($this->count)];
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -33,11 +33,11 @@ use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
use ColoredTrait;
|
||||
use ColorInMetadataTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
@ -53,7 +53,7 @@ class Carpet extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
if($down->getId() !== BlockLegacyIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ class Carpet extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::AIR){
|
||||
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class Carrot extends Crops{
|
||||
];
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaItems::CARROT();
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\CartographyTableInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
final class CartographyTable extends Opaque{
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
$player->setCurrentWindow(new CartographyTableInventory($this->position));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -23,10 +23,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
|
||||
class CarvedPumpkin extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b11;
|
||||
}
|
||||
}
|
||||
|
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Cauldron as TileCauldron;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemTypeIds;
|
||||
use pocketmine\item\Potion;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SplashPotion;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use function assert;
|
||||
|
||||
final class Cauldron extends Transparent{
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
parent::writeStateToWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
assert($tile instanceof TileCauldron);
|
||||
|
||||
//empty cauldrons don't use this information
|
||||
$tile->setCustomWaterColor(null);
|
||||
$tile->setPotionItem(null);
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$result = [
|
||||
AxisAlignedBB::one()->trim(Facing::UP, 11 / 16) //bottom of the cauldron
|
||||
];
|
||||
|
||||
foreach(Facing::HORIZONTAL as $f){ //add the frame parts around the bowl
|
||||
$result[] = AxisAlignedBB::one()->trim($f, 14 / 16);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $facing === Facing::UP ? SupportType::EDGE() : SupportType::NONE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
private function fill(int $amount, FillableCauldron $result, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $result->setFillLevel($amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $result->getFillSound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item->getTypeId() === ItemTypeIds::WATER_BUCKET){
|
||||
$this->fill(FillableCauldron::MAX_FILL_LEVEL, VanillaBlocks::WATER_CAULDRON(), $item, VanillaItems::BUCKET(), $returnedItems);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::LAVA_BUCKET){
|
||||
$this->fill(FillableCauldron::MAX_FILL_LEVEL, VanillaBlocks::LAVA_CAULDRON(), $item, VanillaItems::BUCKET(), $returnedItems);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::POWDER_SNOW_BUCKET){
|
||||
//TODO: powder snow cauldron
|
||||
}elseif($item instanceof Potion || $item instanceof SplashPotion){ //TODO: lingering potion
|
||||
if($item->getType()->equals(PotionType::WATER())){
|
||||
$this->fill(WaterCauldron::WATER_BOTTLE_FILL_AMOUNT, VanillaBlocks::WATER_CAULDRON(), $item, VanillaItems::GLASS_BOTTLE(), $returnedItems);
|
||||
}else{
|
||||
$this->fill(PotionCauldron::POTION_FILL_AMOUNT, VanillaBlocks::POTION_CAULDRON()->setPotionItem($item), $item, VanillaItems::GLASS_BOTTLE(), $returnedItems);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if($world->getBlock($this->position->up())->getTypeId() === BlockTypeIds::WATER){
|
||||
$cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL);
|
||||
$world->setBlock($this->position, $cauldron);
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), $cauldron->getFillSound());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
final class Chain extends Transparent{
|
||||
use PillarRotationTrait;
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $this->axis === Axis::Y && Facing::axis($facing) === Axis::Y ? SupportType::CENTER() : SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$bb = AxisAlignedBB::one();
|
||||
foreach([Axis::Y, Axis::Z, Axis::X] as $axis){
|
||||
if($axis !== $this->axis){
|
||||
$bb->squash($axis, 13 / 32);
|
||||
}
|
||||
}
|
||||
return [$bb];
|
||||
}
|
||||
}
|
@ -23,9 +23,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
@ -33,7 +35,19 @@ final class ChemistryTable extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3));
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing));
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b0011;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
//TODO
|
||||
return false;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Chest as TileChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\ChestPairEvent;
|
||||
use pocketmine\item\Item;
|
||||
@ -36,7 +36,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class Chest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait;
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
@ -74,7 +74,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
$chest = $this->position->getWorld()->getTile($this->position);
|
||||
|
@ -1,233 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\sound\ChorusFlowerDieSound;
|
||||
use pocketmine\world\sound\ChorusFlowerGrowSound;
|
||||
use pocketmine\world\World;
|
||||
use function array_rand;
|
||||
use function mt_rand;
|
||||
|
||||
final class ChorusFlower extends Flowable{
|
||||
public const MIN_AGE = 0;
|
||||
public const MAX_AGE = 5;
|
||||
|
||||
private const MAX_STEM_HEIGHT = 5;
|
||||
|
||||
private int $age = self::MIN_AGE;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, self::MIN_AGE, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
|
||||
/** @return $this */
|
||||
public function setAge(int $age) : self{
|
||||
if($age < self::MIN_AGE || $age > self::MAX_AGE){
|
||||
throw new \InvalidArgumentException("Age must be in the range " . self::MIN_AGE . " ... " . self::MAX_AGE);
|
||||
}
|
||||
$this->age = $age;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()];
|
||||
}
|
||||
|
||||
private function canBeSupportedAt(Position $position) : bool{
|
||||
$world = $position->getWorld();
|
||||
$down = $world->getBlock($position->down());
|
||||
|
||||
if($down->getTypeId() === BlockTypeIds::END_STONE || $down->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
return true;
|
||||
}
|
||||
|
||||
$plantAdjacent = false;
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){
|
||||
$block = $world->getBlock($sidePosition);
|
||||
|
||||
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
if($plantAdjacent){ //at most one plant may be horizontally adjacent
|
||||
return false;
|
||||
}
|
||||
$plantAdjacent = true;
|
||||
}elseif($block->getTypeId() !== BlockTypeIds::AIR){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $plantAdjacent;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedAt($blockReplace->getPosition())){
|
||||
return false;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedAt($this->position)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{ return $this->age < self::MAX_AGE; }
|
||||
|
||||
/**
|
||||
* @phpstan-return array{int, bool}
|
||||
*/
|
||||
private function scanStem() : array{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$stemHeight = 0;
|
||||
$endStoneBelow = false;
|
||||
for($yOffset = 0; $yOffset < self::MAX_STEM_HEIGHT; $yOffset++, $stemHeight++){
|
||||
$down = $world->getBlock($this->position->down($yOffset + 1));
|
||||
|
||||
if($down->getTypeId() !== BlockTypeIds::CHORUS_PLANT){
|
||||
if($down->getTypeId() === BlockTypeIds::END_STONE){
|
||||
$endStoneBelow = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [$stemHeight, $endStoneBelow];
|
||||
}
|
||||
|
||||
private function allHorizontalBlocksEmpty(World $world, Vector3 $position, ?int $except) : bool{
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $facing => $sidePosition){
|
||||
if($facing === $except){
|
||||
continue;
|
||||
}
|
||||
if($world->getBlock($sidePosition)->getTypeId() !== BlockTypeIds::AIR){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canGrowUpwards(int $stemHeight, bool $endStoneBelow) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$up = $this->position->up();
|
||||
if(
|
||||
//the space above must be empty and writable
|
||||
!$world->isInWorld($up->x, $up->y, $up->z) ||
|
||||
$world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR ||
|
||||
(
|
||||
//the space above that must be empty, but doesn't need to be writable
|
||||
$world->isInWorld($up->x, $up->y + 1, $up->z) &&
|
||||
$world->getBlock($up->up())->getTypeId() !== BlockTypeIds::AIR
|
||||
)
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() !== BlockTypeIds::AIR){
|
||||
if($stemHeight >= self::MAX_STEM_HEIGHT){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($stemHeight > 1 && $stemHeight > mt_rand(0, $endStoneBelow ? 4 : 3)){ //chance decreases for each added block of chorus plant
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->allHorizontalBlocksEmpty($world, $up, null);
|
||||
}
|
||||
|
||||
private function grow(int $facing, int $ageChange, ?BlockTransaction $tx) : BlockTransaction{
|
||||
if($tx === null){
|
||||
$tx = new BlockTransaction($this->position->getWorld());
|
||||
}
|
||||
$tx->addBlock($this->position->getSide($facing), (clone $this)->setAge($this->getAge() + $ageChange));
|
||||
|
||||
return $tx;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
if($this->age >= self::MAX_AGE){
|
||||
return;
|
||||
}
|
||||
|
||||
$tx = null;
|
||||
|
||||
[$stemHeight, $endStoneBelow] = $this->scanStem();
|
||||
if($this->canGrowUpwards($stemHeight, $endStoneBelow)){
|
||||
$tx = $this->grow(Facing::UP, 0, $tx);
|
||||
}else{
|
||||
$facingVisited = [];
|
||||
for($attempts = 0, $maxAttempts = mt_rand(0, $endStoneBelow ? 4 : 3); $attempts < $maxAttempts; $attempts++){
|
||||
$facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
|
||||
if(isset($facingVisited[$facing])){
|
||||
continue;
|
||||
}
|
||||
$facingVisited[$facing] = true;
|
||||
|
||||
$sidePosition = $this->position->getSide($facing);
|
||||
if(
|
||||
$world->getBlock($sidePosition)->getTypeId() === BlockTypeIds::AIR &&
|
||||
$world->getBlock($sidePosition->down())->getTypeId() === BlockTypeIds::AIR &&
|
||||
$this->allHorizontalBlocksEmpty($world, $sidePosition, Facing::opposite($facing))
|
||||
){
|
||||
$tx = $this->grow($facing, 1, $tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($tx !== null){
|
||||
$tx->addBlock($this->position, VanillaBlocks::CHORUS_PLANT());
|
||||
$ev = new StructureGrowEvent($this, $tx, null);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled() && $tx->apply()){
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerGrowSound());
|
||||
}
|
||||
}else{
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerDieSound());
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setAge(self::MAX_AGE));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
use function mt_rand;
|
||||
|
||||
final class ChorusPlant extends Flowable{
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$bb = AxisAlignedBB::one();
|
||||
foreach($this->getAllSides() as $facing => $block){
|
||||
$id = $block->getTypeId();
|
||||
if($id !== BlockTypeIds::END_STONE && $id !== BlockTypeIds::CHORUS_FLOWER && !$block->isSameType($this)){
|
||||
$bb->trim($facing, 2 / 16);
|
||||
}
|
||||
}
|
||||
|
||||
return [$bb];
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSameType($this) || $block->getTypeId() === BlockTypeIds::END_STONE;
|
||||
}
|
||||
|
||||
private function canStay(Position $position) : bool{
|
||||
$world = $position->getWorld();
|
||||
|
||||
$down = $world->getBlock($position->down());
|
||||
$verticalAir = $down->getTypeId() === BlockTypeIds::AIR || $world->getBlock($position->up())->getTypeId() === BlockTypeIds::AIR;
|
||||
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){
|
||||
$block = $world->getBlock($sidePosition);
|
||||
|
||||
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
if(!$verticalAir){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->canBeSupportedBy($block->getSide(Facing::DOWN))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->canBeSupportedBy($down)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canStay($blockReplace->getPosition())){
|
||||
return false;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canStay($this->position)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(0, 1) === 1){
|
||||
return [VanillaItems::CHORUS_FRUIT()];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
@ -46,9 +46,17 @@ class CocoaBlock extends Transparent{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->boundedInt(2, 0, self::MAX_AGE, $this->age);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)) | ($this->age << 2);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03));
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta >> 2, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -81,7 +89,7 @@ class CocoaBlock extends Transparent{
|
||||
}
|
||||
|
||||
private function canAttachTo(Block $block) : bool{
|
||||
return $block instanceof Wood && $block->getWoodType()->equals(WoodType::JUNGLE());
|
||||
return $block instanceof Wood && $block->getTreeType()->equals(TreeType::JUNGLE());
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
@ -93,7 +101,7 @@ class CocoaBlock extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($item instanceof Fertilizer && $this->grow()){
|
||||
$item->pop();
|
||||
|
||||
@ -139,7 +147,7 @@ class CocoaBlock extends Transparent{
|
||||
];
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaItems::COCOA_BEANS();
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class Concrete extends Opaque{
|
||||
use ColoredTrait;
|
||||
use ColorInMetadataTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\block\utils\FallableTrait;
|
||||
@ -31,19 +31,19 @@ use pocketmine\event\block\BlockFormEvent;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
class ConcretePowder extends Opaque implements Fallable{
|
||||
use ColoredTrait;
|
||||
use ColorInMetadataTrait;
|
||||
use FallableTrait {
|
||||
onNearbyBlockChange as protected startFalling;
|
||||
}
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(($water = $this->getAdjacentWater()) !== null){
|
||||
$ev = new BlockFormEvent($this, VanillaBlocks::CONCRETE()->setColor($this->color), $water);
|
||||
if(($block = $this->checkAdjacentWater()) !== null){
|
||||
$ev = new BlockFormEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
@ -54,20 +54,16 @@ class ConcretePowder extends Opaque implements Fallable{
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
if($this->getAdjacentWater() === null){
|
||||
return null;
|
||||
}
|
||||
return VanillaBlocks::CONCRETE()->setColor($this->color);
|
||||
return $this->checkAdjacentWater();
|
||||
}
|
||||
|
||||
private function getAdjacentWater() : ?Water{
|
||||
private function checkAdjacentWater() : ?Block{
|
||||
foreach(Facing::ALL as $i){
|
||||
if($i === Facing::DOWN){
|
||||
continue;
|
||||
}
|
||||
$block = $this->getSide($i);
|
||||
if($block instanceof Water){
|
||||
return $block;
|
||||
if($this->getSide($i) instanceof Water){
|
||||
return VanillaBlocks::CONCRETE()->setColor($this->color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class Copper extends Opaque{
|
||||
use CopperTrait;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
|
||||
final class CopperOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [VanillaItems::RAW_COPPER()];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class CopperSlab extends Slab{
|
||||
use CopperTrait;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class CopperStairs extends Stair{
|
||||
use CopperTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->oxidation = CopperOxidation::NONE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -31,6 +33,38 @@ use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class Coral extends BaseCoral{
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
return CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b0111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
//TODO: this hack ensures correct state of coral plants, because they don't retain their dead flag in metadata
|
||||
$world = $this->position->getWorld();
|
||||
$this->dead = true;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$this->dead = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){
|
||||
return false;
|
||||
|
@ -25,6 +25,8 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
@ -32,9 +34,30 @@ use function mt_rand;
|
||||
final class CoralBlock extends Opaque{
|
||||
use CoralTypeTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->coralType = CoralType::TUBE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & 0x7);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
$this->dead = ($stateMeta & BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return ($this->dead ? BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD : 0) | CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
@ -30,7 +30,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class CraftingTable extends Opaque{
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCurrentWindow(new CraftingTableInventory($this->position));
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
@ -38,8 +38,16 @@ abstract class Crops extends Flowable{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_AGE, $this->age);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -54,14 +62,14 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::FARMLAND){
|
||||
if($blockReplace->getSide(Facing::DOWN)->getId() === BlockLegacyIds::FARMLAND){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->age < self::MAX_AGE && $item instanceof Fertilizer){
|
||||
$block = clone $this;
|
||||
$block->age += mt_rand(2, 5);
|
||||
@ -83,7 +91,7 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() !== BlockTypeIds::FARMLAND){
|
||||
if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -39,11 +39,30 @@ use const M_PI;
|
||||
class DaylightSensor extends Transparent{
|
||||
use AnalogRedstoneSignalEmitterTrait;
|
||||
|
||||
protected BlockIdentifierFlattened $idInfoFlattened;
|
||||
|
||||
protected bool $inverted = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, 15, $this->signalStrength);
|
||||
$w->bool($this->inverted);
|
||||
public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->idInfoFlattened = $idInfo;
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
return $this->inverted ? $this->idInfoFlattened->getSecondId() : parent::getId();
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->signalStrength;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15);
|
||||
$this->inverted = $id === $this->idInfoFlattened->getSecondId();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function isInverted() : bool{
|
||||
@ -73,7 +92,7 @@ class DaylightSensor extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->inverted = !$this->inverted;
|
||||
$this->signalStrength = $this->recalculateSignalStrength();
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
|
@ -66,13 +66,12 @@ class DeadBush extends Flowable{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
$blockId = $block->getTypeId();
|
||||
return $blockId === BlockTypeIds::SAND
|
||||
|| $blockId === BlockTypeIds::RED_SAND
|
||||
|| $blockId === BlockTypeIds::PODZOL
|
||||
|| $blockId === BlockTypeIds::MYCELIUM
|
||||
|| $blockId === BlockTypeIds::DIRT
|
||||
|| $blockId === BlockTypeIds::HARDENED_CLAY
|
||||
|| $blockId === BlockTypeIds::STAINED_CLAY;
|
||||
$blockId = $block->getId();
|
||||
return $blockId === BlockLegacyIds::SAND
|
||||
|| $blockId === BlockLegacyIds::PODZOL
|
||||
|| $blockId === BlockLegacyIds::MYCELIUM
|
||||
|| $blockId === BlockLegacyIds::DIRT
|
||||
|| $blockId === BlockLegacyIds::HARDENED_CLAY
|
||||
|| $blockId === BlockLegacyIds::STAINED_HARDENED_CLAY;
|
||||
}
|
||||
}
|
||||
|
@ -23,16 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
|
||||
class DetectorRail extends StraightOnlyRail{
|
||||
protected bool $activated = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
parent::describeState($w);
|
||||
$w->bool($this->activated);
|
||||
}
|
||||
|
||||
public function isActivated() : bool{ return $this->activated; }
|
||||
|
||||
/** @return $this */
|
||||
@ -40,5 +33,19 @@ class DetectorRail extends StraightOnlyRail{
|
||||
$this->activated = $activated;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
parent::readStateFromData($id, $stateMeta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED);
|
||||
$this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return parent::writeStateToMeta() | ($this->activated ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -23,67 +23,50 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Hoe;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Potion;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SplashPotion;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\sound\ItemUseOnBlockSound;
|
||||
use pocketmine\world\sound\WaterSplashSound;
|
||||
|
||||
class Dirt extends Opaque{
|
||||
protected DirtType $dirtType;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->dirtType = DirtType::NORMAL();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
protected bool $coarse = false;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->coarse = ($stateMeta & BlockLegacyMetadata::DIRT_FLAG_COARSE) !== 0;
|
||||
}
|
||||
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
$w->dirtType($this->dirtType);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->coarse ? BlockLegacyMetadata::DIRT_FLAG_COARSE : 0;
|
||||
}
|
||||
|
||||
public function getDirtType() : DirtType{ return $this->dirtType; }
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1;
|
||||
}
|
||||
|
||||
public function isCoarse() : bool{ return $this->coarse; }
|
||||
|
||||
/** @return $this */
|
||||
public function setDirtType(DirtType $dirtType) : self{
|
||||
$this->dirtType = $dirtType;
|
||||
public function setCoarse(bool $coarse) : self{
|
||||
$this->coarse = $coarse;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face === Facing::UP && $item instanceof Hoe){
|
||||
$item->applyDamage(1);
|
||||
|
||||
$newBlock = $this->dirtType->equals(DirtType::NORMAL()) ? VanillaBlocks::FARMLAND() : VanillaBlocks::DIRT();
|
||||
$center = $this->position->add(0.5, 0.5, 0.5);
|
||||
$world->addSound($center, new ItemUseOnBlockSound($newBlock));
|
||||
$newBlock = $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND();
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
|
||||
$world->setBlock($this->position, $newBlock);
|
||||
if($this->dirtType->equals(DirtType::ROOTED())){
|
||||
$world->dropItem($center, VanillaBlocks::HANGING_ROOTS()->asItem());
|
||||
}
|
||||
|
||||
return true;
|
||||
}elseif($this->dirtType->equals(DirtType::ROOTED()) && $item instanceof Fertilizer){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
return true;
|
||||
}
|
||||
|
||||
$item->pop();
|
||||
$world->setBlock($down->position, VanillaBlocks::HANGING_ROOTS());
|
||||
//TODO: bonemeal particles, growth sounds
|
||||
}elseif(($item instanceof Potion || $item instanceof SplashPotion) && $item->getType()->equals(PotionType::WATER())){
|
||||
$item->pop();
|
||||
$world->setBlock($this->position, VanillaBlocks::MUD());
|
||||
$world->addSound($this->position, new WaterSplashSound(0.5));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\PoweredByRedstoneTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -36,19 +37,38 @@ use pocketmine\world\sound\DoorSound;
|
||||
|
||||
class Door extends Transparent{
|
||||
use HorizontalFacingTrait;
|
||||
use PoweredByRedstoneTrait;
|
||||
|
||||
protected bool $top = false;
|
||||
protected bool $hingeRight = false;
|
||||
protected bool $open = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->top);
|
||||
$w->bool($this->hingeRight);
|
||||
$w->bool($this->open);
|
||||
protected function writeStateToMeta() : int{
|
||||
if($this->top){
|
||||
return BlockLegacyMetadata::DOOR_FLAG_TOP |
|
||||
($this->hingeRight ? BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT : 0) |
|
||||
($this->powered ? BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::rotateY($this->facing, true)) | ($this->open ? BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN : 0);
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->top = ($stateMeta & BlockLegacyMetadata::DOOR_FLAG_TOP) !== 0;
|
||||
if($this->top){
|
||||
$this->hingeRight = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT) !== 0;
|
||||
$this->powered = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED) !== 0;
|
||||
}else{
|
||||
$this->facing = Facing::rotateY(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03), false);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN) !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
parent::readStateFromWorld();
|
||||
|
||||
//copy door properties from other half
|
||||
@ -59,10 +79,9 @@ class Door extends Transparent{
|
||||
$this->open = $other->open;
|
||||
}else{
|
||||
$this->hingeRight = $other->hingeRight;
|
||||
$this->powered = $other->powered;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isTop() : bool{ return $this->top; }
|
||||
@ -140,7 +159,7 @@ class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->open = !$this->open;
|
||||
|
||||
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -31,10 +30,19 @@ use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
|
||||
protected bool $top = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->top);
|
||||
protected function writeStateToMeta() : int{
|
||||
return ($this->top ? BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->top = ($stateMeta & BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1000;
|
||||
}
|
||||
|
||||
public function isTop() : bool{ return $this->top; }
|
||||
@ -46,8 +54,8 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
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->hasTypeTag(BlockTypeTags::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$id = $blockReplace->getSide(Facing::DOWN)->getId();
|
||||
if(($id === BlockLegacyIds::GRASS || $id === BlockLegacyIds::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$top = clone $this;
|
||||
$top->top = true;
|
||||
$tx->addBlock($blockReplace->position, $this)->addBlock($blockReplace->position->getSide(Facing::UP), $top);
|
||||
@ -71,8 +79,7 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && !$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD))){
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && $this->getSide(Facing::DOWN)->isTransparent())){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,11 @@ class DragonEgg extends Transparent implements Fallable{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->teleport();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class DyedCandle extends Candle{
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function getCandleIfCompatibleType(Block $block) : ?Candle{
|
||||
$result = parent::getCandleIfCompatibleType($block);
|
||||
//different coloured candles can't be combined in the same block
|
||||
return $result instanceof DyedCandle && $result->color->equals($this->color) ? $result : null;
|
||||
}
|
||||
}
|
@ -23,14 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
final class DyedShulkerBox extends ShulkerBox{
|
||||
use ColoredTrait;
|
||||
use ColorInMetadataTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ class Element extends Opaque{
|
||||
public function __construct(
|
||||
BlockIdentifier $idInfo,
|
||||
string $name,
|
||||
BlockTypeInfo $typeInfo,
|
||||
BlockBreakInfo $breakInfo,
|
||||
private string $symbol,
|
||||
private int $atomicWeight,
|
||||
private int $group
|
||||
){
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function getAtomicWeight() : int{
|
||||
|
@ -44,7 +44,7 @@ class EnchantingTable extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
//TODO lock
|
||||
|
||||
|
@ -23,9 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
@ -35,9 +35,17 @@ class EndPortalFrame extends Opaque{
|
||||
|
||||
protected bool $eye = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->eye);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->eye = ($stateMeta & BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
public function hasEye() : bool{ return $this->eye; }
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -35,6 +36,27 @@ use pocketmine\world\BlockTransaction;
|
||||
class EndRod extends Flowable{
|
||||
use AnyFacingTrait;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
$result = BlockDataSerializer::writeFacing($this->facing);
|
||||
if(Facing::axis($this->facing) !== Axis::Y){
|
||||
$result ^= 1; //TODO: in PC this is always the same as facing, just PE is stupid
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
if($stateMeta !== 0 && $stateMeta !== 1){
|
||||
$stateMeta ^= 1;
|
||||
}
|
||||
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->facing = $face;
|
||||
if($blockClicked instanceof EndRod && $blockClicked->facing === $this->facing){
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\inventory\EnderChestInventory;
|
||||
use pocketmine\block\tile\EnderChest as TileEnderChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -36,7 +36,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class EnderChest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait;
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 7;
|
||||
@ -54,7 +54,7 @@ class EnderChest extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$enderChest = $this->position->getWorld()->getTile($this->position);
|
||||
if($enderChest instanceof TileEnderChest && $this->getSide(Facing::UP)->isTransparent()){
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\event\entity\EntityTrampleFarmlandEvent;
|
||||
@ -37,8 +37,16 @@ class Farmland extends Transparent{
|
||||
|
||||
protected int $wetness = 0; //"moisture" blockstate property in PC
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_WETNESS, $this->wetness);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->wetness;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->wetness = BlockDataSerializer::readBoundedInt("wetness", $stateMeta, 0, self::MAX_WETNESS);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
public function getWetness() : int{ return $this->wetness; }
|
||||
|
@ -37,7 +37,7 @@ class Fence extends Transparent{
|
||||
return 0.25;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : Block{
|
||||
public function readStateFromWorld() : void{
|
||||
parent::readStateFromWorld();
|
||||
|
||||
foreach(Facing::HORIZONTAL as $facing){
|
||||
@ -48,8 +48,6 @@ class Fence extends Transparent{
|
||||
unset($this->connections[$facing]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,10 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\WoodTypeTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -36,16 +35,25 @@ use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\DoorSound;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
use WoodTypeTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected bool $open = false;
|
||||
protected bool $inWall = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->open);
|
||||
$w->bool($this->inWall);
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) |
|
||||
($this->open ? BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN : 0) |
|
||||
($this->inWall ? BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN) !== 0;
|
||||
$this->inWall = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function isOpen() : bool{ return $this->open; }
|
||||
@ -100,7 +108,7 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->open = !$this->open;
|
||||
if($this->open && $player !== null){
|
||||
$playerFacing = $player->getHorizontalFacing();
|
||||
@ -116,14 +124,14 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return $this->woodType->isFlammable() ? 300 : 0;
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return $this->woodType->isFlammable() ? 5 : 0;
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return $this->woodType->isFlammable() ? 20 : 0;
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
@ -1,127 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\world\sound\Sound;
|
||||
use function min;
|
||||
|
||||
abstract class FillableCauldron extends Transparent{
|
||||
public const MIN_FILL_LEVEL = 1;
|
||||
public const MAX_FILL_LEVEL = 6;
|
||||
|
||||
private int $fillLevel = self::MIN_FILL_LEVEL;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, self::MIN_FILL_LEVEL, self::MAX_FILL_LEVEL, $this->fillLevel);
|
||||
}
|
||||
|
||||
public function getFillLevel() : int{ return $this->fillLevel; }
|
||||
|
||||
/** @return $this */
|
||||
public function setFillLevel(int $fillLevel) : self{
|
||||
if($fillLevel < self::MIN_FILL_LEVEL || $fillLevel > self::MAX_FILL_LEVEL){
|
||||
throw new \InvalidArgumentException("Fill level must be in range " . self::MIN_FILL_LEVEL . " ... " . self::MAX_FILL_LEVEL);
|
||||
}
|
||||
$this->fillLevel = $fillLevel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$result = [
|
||||
AxisAlignedBB::one()->trim(Facing::UP, 11 / 16) //bottom of the cauldron
|
||||
];
|
||||
|
||||
foreach(Facing::HORIZONTAL as $f){ //add the frame parts around the bowl
|
||||
$result[] = AxisAlignedBB::one()->trim($f, 14 / 16);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $facing === Facing::UP ? SupportType::EDGE() : SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function withFillLevel(int $fillLevel) : Block{
|
||||
return $fillLevel === 0 ? VanillaBlocks::CAULDRON() : $this->setFillLevel(min(self::MAX_FILL_LEVEL, $fillLevel));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function addFillLevels(int $amount, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
if($this->fillLevel >= self::MAX_FILL_LEVEL){
|
||||
return;
|
||||
}
|
||||
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel + $amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getFillSound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function removeFillLevels(int $amount, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
if($this->fillLevel < $amount){
|
||||
return;
|
||||
}
|
||||
|
||||
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel - $amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getEmptySound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound played when adding levels to the cauldron liquid.
|
||||
*/
|
||||
abstract public function getFillSound() : Sound;
|
||||
|
||||
/**
|
||||
* Returns the sound played when removing levels from the cauldron liquid.
|
||||
*/
|
||||
abstract public function getEmptySound() : Sound;
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function mix(Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::CAULDRON());
|
||||
//TODO: sounds and particles
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaBlocks::CAULDRON()->asItem();
|
||||
}
|
||||
}
|
@ -23,9 +23,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Arrow;
|
||||
use pocketmine\event\block\BlockBurnEvent;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\World;
|
||||
@ -34,13 +40,21 @@ use function max;
|
||||
use function min;
|
||||
use function mt_rand;
|
||||
|
||||
class Fire extends BaseFire{
|
||||
class Fire extends Flowable{
|
||||
public const MAX_AGE = 15;
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, self::MAX_AGE, $this->age);
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -54,16 +68,40 @@ class Fire extends BaseFire{
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getFireDamage() : int{
|
||||
return 1;
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
$ev->cancel();
|
||||
}
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
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()){
|
||||
if($this->getSide(Facing::DOWN)->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
|
||||
@ -189,7 +227,7 @@ class Fire extends BaseFire{
|
||||
continue;
|
||||
}
|
||||
$block = $world->getBlockAt($targetX, $targetY, $targetZ);
|
||||
if($block->getTypeId() !== BlockTypeIds::AIR){
|
||||
if($block->getId() !== BlockLegacyIds::AIR){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,18 @@ use pocketmine\world\BlockTransaction;
|
||||
final class FloorBanner extends BaseBanner{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->rotation = $stateMeta;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::DOWN;
|
||||
}
|
||||
|
@ -23,9 +23,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\ItemIds;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -35,10 +37,49 @@ use function atan2;
|
||||
use function rad2deg;
|
||||
|
||||
final class FloorCoralFan extends BaseCoral{
|
||||
|
||||
protected BlockIdentifierFlattened $idInfoFlattened;
|
||||
|
||||
private int $axis = Axis::X;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalAxis($this->axis);
|
||||
public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->idInfoFlattened = $idInfo;
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->dead = $id === $this->idInfoFlattened->getSecondId();
|
||||
$this->axis = ($stateMeta >> 3) === BlockLegacyMetadata::CORAL_FAN_EAST_WEST ? Axis::X : Axis::Z;
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & BlockLegacyMetadata::CORAL_FAN_TYPE_MASK);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
return $this->dead ? $this->idInfoFlattened->getSecondId() : parent::getId();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
//TODO: HACK! workaround dead flag being lost when broken / blockpicked (original impl only uses first ID)
|
||||
return ItemFactory::getInstance()->get(
|
||||
$this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN,
|
||||
$this->writeStateToItemMeta()
|
||||
);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return (($this->axis === Axis::X ? BlockLegacyMetadata::CORAL_FAN_EAST_WEST : BlockLegacyMetadata::CORAL_FAN_NORTH_SOUTH) << 3) |
|
||||
CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function getAxis() : int{ return $this->axis; }
|
||||
@ -67,9 +108,6 @@ final class FloorCoralFan extends BaseCoral{
|
||||
$this->axis = Axis::Z;
|
||||
}
|
||||
}
|
||||
|
||||
$this->dead = !$this->isCoveredWithWater();
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -86,7 +124,4 @@ final class FloorCoralFan extends BaseCoral{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::CORAL_FAN()->setCoralType($this->coralType)->setDead($this->dead);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user