PocketMine-MP 5.18.1 git-9381fc4172e5dce4cada1cb356050c8a2ab57b94
BlockStateDeserializerHelper.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20 */
21
22declare(strict_types=1);
23
24namespace pocketmine\data\bedrock\block\convert;
25
51use pocketmine\block\utils\CopperOxidation;
52use pocketmine\block\utils\SlabType;
68
70
72 public static function decodeButton(Button $block, BlockStateReader $in) : Button{
73 return $block
74 ->setFacing($in->readFacingDirection())
75 ->setPressed($in->readBool(BlockStateNames::BUTTON_PRESSED_BIT));
76 }
77
79 public static function decodeCandle(Candle $block, BlockStateReader $in) : Candle{
80 return $block
81 ->setCount($in->readBoundedInt(StateNames::CANDLES, 0, 3) + 1)
82 ->setLit($in->readBool(StateNames::LIT));
83 }
84
92 public static function decodeCrops(Crops $block, BlockStateReader $in) : Crops{
93 return $block->setAge($in->readBoundedInt(BlockStateNames::GROWTH, 0, 7));
94 }
95
98 return $block
99 ->setFacing($in->readCardinalHorizontalFacing())
100 ->setPowered($in->readBool(BlockStateNames::OUTPUT_LIT_BIT))
101 ->setSubtractMode($in->readBool(BlockStateNames::OUTPUT_SUBTRACT_BIT));
102 }
103
110 public static function decodeCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation) : Copper|CopperSlab|CopperStairs{
111 $block->setOxidation($oxidation);
112 $block->setWaxed(false);
113 return $block;
114 }
115
122 public static function decodeWaxedCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation) : Copper|CopperSlab|CopperStairs{
123 $block->setOxidation($oxidation);
124 $block->setWaxed(true);
125 return $block;
126 }
127
130 return $block
131 ->setOutputSignalStrength($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15));
132 }
133
135 public static function decodeDoor(Door $block, BlockStateReader $in) : Door{
136 //TODO: check if these need any special treatment to get the appropriate data to both halves of the door
137 return $block
138 ->setTop($in->readBool(BlockStateNames::UPPER_BLOCK_BIT))
139 ->setFacing(Facing::rotateY($in->readLegacyHorizontalFacing(), false))
140 ->setHingeRight($in->readBool(BlockStateNames::DOOR_HINGE_BIT))
141 ->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
142 }
143
145 public static function decodeDoublePlant(DoublePlant $block, BlockStateReader $in) : DoublePlant{
146 return $block
147 ->setTop($in->readBool(BlockStateNames::UPPER_BLOCK_BIT));
148 }
149
151 public static function decodeFenceGate(FenceGate $block, BlockStateReader $in) : FenceGate{
152 return $block
153 ->setFacing($in->readLegacyHorizontalFacing())
154 ->setInWall($in->readBool(BlockStateNames::IN_WALL_BIT))
155 ->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
156 }
157
160 return $block
161 ->setAxis(match($in->readBoundedInt(BlockStateNames::CORAL_FAN_DIRECTION, 0, 1)){
162 0 => Axis::X,
163 1 => Axis::Z,
164 default => throw new AssumptionFailedError("readBoundedInt() should have prevented this"),
165 });
166 }
167
169 public static function decodeFloorSign(FloorSign $block, BlockStateReader $in) : FloorSign{
170 return $block
171 ->setRotation($in->readBoundedInt(BlockStateNames::GROUND_SIGN_DIRECTION, 0, 15));
172 }
173
174 public static function decodeItemFrame(ItemFrame $block, BlockStateReader $in) : ItemFrame{
175 $in->todo(StateNames::ITEM_FRAME_PHOTO_BIT); //TODO: not sure what the point of this is
176 return $block
177 ->setFacing($in->readFacingDirection())
178 ->setHasMap($in->readBool(StateNames::ITEM_FRAME_MAP_BIT));
179 }
180
182 public static function decodeLeaves(Leaves $block, BlockStateReader $in) : Leaves{
183 return $block
184 ->setNoDecay($in->readBool(StateNames::PERSISTENT_BIT))
185 ->setCheckDecay($in->readBool(StateNames::UPDATE_BIT));
186 }
187
189 public static function decodeLiquid(Liquid $block, BlockStateReader $in, bool $still) : Liquid{
190 $fluidHeightState = $in->readBoundedInt(BlockStateNames::LIQUID_DEPTH, 0, 15);
191 return $block
192 ->setDecay($fluidHeightState & 0x7)
193 ->setFalling(($fluidHeightState & 0x8) !== 0)
194 ->setStill($still);
195 }
196
197 public static function decodeFlowingLiquid(Liquid $block, BlockStateReader $in) : Liquid{
198 return self::decodeLiquid($block, $in, false);
199 }
200
201 public static function decodeStillLiquid(Liquid $block, BlockStateReader $in) : Liquid{
202 return self::decodeLiquid($block, $in, true);
203 }
204
206 public static function decodeLog(Wood $block, bool $stripped, BlockStateReader $in) : Wood{
207 return $block
208 ->setAxis($in->readPillarAxis())
209 ->setStripped($stripped);
210 }
211
213 public static function decodeMushroomBlock(RedMushroomBlock $block, BlockStateReader $in) : Block{
214 switch($type = $in->readBoundedInt(BlockStateNames::HUGE_MUSHROOM_BITS, 0, 15)){
215 case BlockLegacyMetadata::MUSHROOM_BLOCK_ALL_STEM: return VanillaBlocks::ALL_SIDED_MUSHROOM_STEM();
216 case BlockLegacyMetadata::MUSHROOM_BLOCK_STEM: return VanillaBlocks::MUSHROOM_STEM();
217 default:
218 //invalid types get left as default
219 $type = MushroomBlockTypeIdMap::getInstance()->fromId($type);
220 return $type !== null ? $block->setMushroomBlockType($type) : $block;
221 }
222 }
223
226 return $block
227 ->setFacing($in->readCardinalHorizontalFacing())
228 ->setDelay($in->readBoundedInt(BlockStateNames::REPEATER_DELAY, 0, 3) + 1);
229 }
230
232 public static function decodeSapling(Sapling $block, BlockStateReader $in) : Sapling{
233 return $block
234 ->setReady($in->readBool(BlockStateNames::AGE_BIT));
235 }
236
239 //TODO: not sure what the deal is here ... seems like a mojang bug / artifact of bad implementation?
240 //best to keep this separate from weighted plates anyway...
241 return $block->setPressed($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15) !== 0);
242 }
243
245 public static function decodeSingleSlab(Slab $block, BlockStateReader $in) : Slab{
246 return $block->setSlabType($in->readSlabPosition());
247 }
248
250 public static function decodeDoubleSlab(Slab $block, BlockStateReader $in) : Slab{
251 $in->ignored(StateNames::MC_VERTICAL_HALF);
252 return $block->setSlabType(SlabType::DOUBLE);
253 }
254
256 public static function decodeStairs(Stair $block, BlockStateReader $in) : Stair{
257 return $block
258 ->setUpsideDown($in->readBool(BlockStateNames::UPSIDE_DOWN_BIT))
259 ->setFacing($in->readWeirdoHorizontalFacing());
260 }
261
263 public static function decodeStem(Stem $block, BlockStateReader $in) : Stem{
264 //In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the
265 //most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which
266 //is absurd, and I refuse to make our API similarly absurd.
267 $facing = $in->readFacingWithoutUp();
268 return self::decodeCrops($block, $in)
269 ->setFacing($facing === Facing::DOWN ? Facing::UP : $facing);
270 }
271
273 public static function decodeTrapdoor(Trapdoor $block, BlockStateReader $in) : Trapdoor{
274 return $block
275 ->setFacing($in->read5MinusHorizontalFacing())
276 ->setTop($in->readBool(BlockStateNames::UPSIDE_DOWN_BIT))
277 ->setOpen($in->readBool(BlockStateNames::OPEN_BIT));
278 }
279
281 public static function decodeWall(Wall $block, BlockStateReader $in) : Wall{
282 $block->setPost($in->readBool(BlockStateNames::WALL_POST_BIT));
283 $block->setConnection(Facing::NORTH, $in->readWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_NORTH));
284 $block->setConnection(Facing::SOUTH, $in->readWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_SOUTH));
285 $block->setConnection(Facing::WEST, $in->readWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_WEST));
286 $block->setConnection(Facing::EAST, $in->readWallConnectionType(BlockStateNames::WALL_CONNECTION_TYPE_EAST));
287
288 return $block;
289 }
290
292 public static function decodeWallCoralFan(WallCoralFan $block, BlockStateReader $in) : WallCoralFan{
293 return $block
294 ->setDead($in->readBool(BlockStateNames::DEAD_BIT))
295 ->setFacing($in->readCoralFacing());
296 }
297
299 public static function decodeWallSign(WallSign $block, BlockStateReader $in) : WallSign{
300 return $block
301 ->setFacing($in->readHorizontalFacing());
302 }
303
304 public static function decodeWeightedPressurePlate(WeightedPressurePlate $block, BlockStateReader $in) : WeightedPressurePlate{
305 return $block
306 ->setOutputSignalStrength($in->readBoundedInt(BlockStateNames::REDSTONE_SIGNAL, 0, 15));
307 }
308
310 public static function mapLegacyWallType(BlockStateReader $in) : Wall{
311 return self::decodeWall(match($type = $in->readString(BlockStateNames::WALL_BLOCK_TYPE)){
312 StringValues::WALL_BLOCK_TYPE_ANDESITE => VanillaBlocks::ANDESITE_WALL(),
313 StringValues::WALL_BLOCK_TYPE_BRICK => VanillaBlocks::BRICK_WALL(),
314 StringValues::WALL_BLOCK_TYPE_COBBLESTONE => VanillaBlocks::COBBLESTONE_WALL(),
315 StringValues::WALL_BLOCK_TYPE_DIORITE => VanillaBlocks::DIORITE_WALL(),
316 StringValues::WALL_BLOCK_TYPE_END_BRICK => VanillaBlocks::END_STONE_BRICK_WALL(),
317 StringValues::WALL_BLOCK_TYPE_GRANITE => VanillaBlocks::GRANITE_WALL(),
318 StringValues::WALL_BLOCK_TYPE_MOSSY_COBBLESTONE => VanillaBlocks::MOSSY_COBBLESTONE_WALL(),
319 StringValues::WALL_BLOCK_TYPE_MOSSY_STONE_BRICK => VanillaBlocks::MOSSY_STONE_BRICK_WALL(),
320 StringValues::WALL_BLOCK_TYPE_NETHER_BRICK => VanillaBlocks::NETHER_BRICK_WALL(),
321 StringValues::WALL_BLOCK_TYPE_PRISMARINE => VanillaBlocks::PRISMARINE_WALL(),
322 StringValues::WALL_BLOCK_TYPE_RED_NETHER_BRICK => VanillaBlocks::RED_NETHER_BRICK_WALL(),
323 StringValues::WALL_BLOCK_TYPE_RED_SANDSTONE => VanillaBlocks::RED_SANDSTONE_WALL(),
324 StringValues::WALL_BLOCK_TYPE_SANDSTONE => VanillaBlocks::SANDSTONE_WALL(),
325 StringValues::WALL_BLOCK_TYPE_STONE_BRICK => VanillaBlocks::STONE_BRICK_WALL(),
326 default => throw $in->badValueException(BlockStateNames::WALL_BLOCK_TYPE, $type),
327 }, $in);
328 }
329}
setDecay(int $decay)
Definition: Liquid.php:68
setMushroomBlockType(MushroomBlockType $mushroomBlockType)
setSlabType(SlabType $slabType)
Definition: Slab.php:61
setConnection(int $face, ?WallConnectionType $type)
Definition: Wall.php:71
static decodeRepeater(RedstoneRepeater $block, BlockStateReader $in)
static decodeMushroomBlock(RedMushroomBlock $block, BlockStateReader $in)
static decodeLiquid(Liquid $block, BlockStateReader $in, bool $still)
static decodeWaxedCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation)
static decodeLog(Wood $block, bool $stripped, BlockStateReader $in)
static decodeDaylightSensor(DaylightSensor $block, BlockStateReader $in)
static decodeFloorCoralFan(FloorCoralFan $block, BlockStateReader $in)
static decodeSimplePressurePlate(SimplePressurePlate $block, BlockStateReader $in)
static decodeCopper(Copper|CopperSlab|CopperStairs $block, CopperOxidation $oxidation)
static decodeComparator(RedstoneComparator $block, BlockStateReader $in)