PocketMine-MP 5.35.1 git-e32e836dad793a3a3c8ddd8927c00e112b1e576a
Loading...
Searching...
No Matches
CommonProperties.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\property;
25
44use pocketmine\block\utils\CopperOxidation;
46use pocketmine\block\utils\CoralType;
47use pocketmine\block\utils\DyeColor;
49use pocketmine\block\utils\HorizontalFacingOption;
54use pocketmine\block\utils\SlabType;
55use pocketmine\block\utils\StraightOnlyRailShape;
63use pocketmine\utils\SingletonTrait;
64
65final class CommonProperties{
66 use SingletonTrait;
67
74
83
86
89
92
95
97 public readonly IntProperty $cropAgeMax7;
102
104 public readonly IntProperty $liquidData;
105
107 public readonly BoolProperty $lit;
108
109 public readonly DummyProperty $dummyCardinalDirection;
110 public readonly DummyProperty $dummyPillarAxis;
111
114
117
122
127 public readonly array $coralIdPrefixes;
132 public readonly array $copperIdPrefixes;
133
138 public readonly array $furnaceIdPrefixes;
139
144 public readonly array $liquidIdPrefixes;
145
150 public readonly array $woodIdPrefixes;
151
156 public readonly array $buttonProperties;
157
162 public readonly array $campfireProperties;
163
168 public readonly array $doorProperties;
169
174 public readonly array $fenceGateProperties;
175
180 public readonly array $itemFrameProperties;
181
186 public readonly array $simplePressurePlateProperties;
187
192 public readonly array $stairProperties;
193
198 public readonly array $stemProperties;
199
204 public readonly array $trapdoorProperties;
205
210 public readonly array $wallProperties;
211
212 private function __construct(){
213 $vm = ValueMappings::getInstance();
214
215 //TODO: crude hack here - since we have no HorizontalFacing enum we need to use ints and convert to enum in the accessors
216 $hfGet = fn(HorizontalFacing $v) => $v->getFacing();
217 $hfSet = fn(HorizontalFacing $v, HorizontalFacingOption $facing) => $v->setFacing($facing);
218 $this->horizontalFacingCardinal = new ValueFromStringProperty(StateNames::MC_CARDINAL_DIRECTION, $vm->cardinalDirection, $hfGet, $hfSet);
219
220 $this->blockFace = new ValueFromStringProperty(
221 StateNames::MC_BLOCK_FACE,
222 $vm->blockFace,
223 fn(AnyFacing $b) => $b->getFacing(),
224 fn(AnyFacing $b, Facing $v) => $b->setFacing($v)
225 );
226
227 $this->pillarAxis = new ValueFromStringProperty(
228 StateNames::PILLAR_AXIS,
229 $vm->pillarAxis,
230 fn(PillarRotation $b) => $b->getAxis(),
231 fn(PillarRotation $b, Axis $v) => $b->setAxis($v)
232 );
233
234 $this->torchFacing = new ValueFromStringProperty(
235 StateNames::TORCH_FACING_DIRECTION,
236 $vm->torchFacing,
237 fn(Torch $b) => $b->getFacing()->value,
238 fn(Torch $b, int $v) => $b->setFacing(Facing::from($v))
239 );
240
241 $this->horizontalFacingSWNE = new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacingSWNE, $hfGet, $hfSet);
242 $this->horizontalFacingSWNEInverted = new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacingSWNEInverted, $hfGet, $hfSet);
243 $this->horizontalFacingClassic = new ValueFromIntProperty(StateNames::FACING_DIRECTION, $vm->horizontalFacingClassic, $hfGet, $hfSet);
244
245 $this->anyFacingClassic = new ValueFromIntProperty(
246 StateNames::FACING_DIRECTION,
247 $vm->facing,
248 fn(AnyFacing $b) => $b->getFacing(),
249 fn(AnyFacing $b, Facing $v) => $b->setFacing($v)
250 );
251
252 $this->multiFacingFlags = new ValueSetFromIntProperty(
253 StateNames::MULTI_FACE_DIRECTION_BITS,
254 EnumFromRawStateMap::int(Facing::class, fn(Facing $case) => match ($case) {
255 Facing::DOWN => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_DOWN,
256 Facing::UP => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_UP,
257 Facing::NORTH => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_NORTH,
258 Facing::SOUTH => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_SOUTH,
259 Facing::WEST => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_WEST,
260 Facing::EAST => BlockLegacyMetadata::MULTI_FACE_DIRECTION_FLAG_EAST
261 }),
262 fn(MultiAnyFacing $b) => $b->getFaces(),
263 fn(MultiAnyFacing $b, array $v) => $b->setFaces($v)
264 );
265
266 $this->floorSignLikeRotation = new IntProperty(StateNames::GROUND_SIGN_DIRECTION, 0, 15, fn(SignLikeRotation $b) => $b->getRotation(), fn(SignLikeRotation $b, int $v) => $b->setRotation($v));
267
268 $this->analogRedstoneSignal = new IntProperty(StateNames::REDSTONE_SIGNAL, 0, 15, fn(AnalogRedstoneSignalEmitter $b) => $b->getOutputSignalStrength(), fn(AnalogRedstoneSignalEmitter $b, int $v) => $b->setOutputSignalStrength($v));
269
270 $this->cropAgeMax7 = new IntProperty(StateNames::GROWTH, 0, 7, fn(Ageable $b) => $b->getAge(), fn(Ageable $b, int $v) => $b->setAge($v));
271 $this->doublePlantHalf = new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(DoublePlant $b) => $b->isTop(), fn(DoublePlant $b, bool $v) => $b->setTop($v));
272
273 $this->straightOnlyRailShape = new ValueFromIntProperty(StateNames::RAIL_DIRECTION, EnumFromRawStateMap::int(StraightOnlyRailShape::class, fn(StraightOnlyRailShape $case) => match($case){
274 StraightOnlyRailShape::FLAT_AXIS_Z => BlockLegacyMetadata::RAIL_STRAIGHT_NORTH_SOUTH,
275 StraightOnlyRailShape::FLAT_AXIS_X => BlockLegacyMetadata::RAIL_STRAIGHT_EAST_WEST,
276 StraightOnlyRailShape::ASCENDING_EAST => BlockLegacyMetadata::RAIL_ASCENDING_EAST,
277 StraightOnlyRailShape::ASCENDING_WEST => BlockLegacyMetadata::RAIL_ASCENDING_WEST,
278 StraightOnlyRailShape::ASCENDING_NORTH => BlockLegacyMetadata::RAIL_ASCENDING_NORTH,
279 StraightOnlyRailShape::ASCENDING_SOUTH => BlockLegacyMetadata::RAIL_ASCENDING_SOUTH
280 }), fn(StraightOnlyRail $b) => $b->getShape(), fn(StraightOnlyRail $b, StraightOnlyRailShape $v) => $b->setShape($v));
281
282 $fallingFlag = BlockLegacyMetadata::LIQUID_FALLING_FLAG;
283 $this->liquidData = new IntProperty(
284 StateNames::LIQUID_DEPTH,
285 0,
286 15,
287 fn(Liquid $b) => $b->getDecay() | ($b->isFalling() ? $fallingFlag : 0),
288 fn(Liquid $b, int $v) => $b->setDecay($v & ~$fallingFlag)->setFalling(($v & $fallingFlag) !== 0)
289 );
290
291 $this->lit = new BoolProperty(StateNames::LIT, fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v));
292
293 $this->dummyCardinalDirection = new DummyProperty(StateNames::MC_CARDINAL_DIRECTION, BlockStateStringValues::MC_CARDINAL_DIRECTION_SOUTH);
294 $this->dummyPillarAxis = new DummyProperty(StateNames::PILLAR_AXIS, BlockStateStringValues::PILLAR_AXIS_Y);
295
296 $this->dyeColorIdInfix = new ValueFromStringProperty("color", $vm->dyeColor, fn(Colored $b) => $b->getColor(), fn(Colored $b, DyeColor $v) => $b->setColor($v));
297 $this->litIdInfix = new BoolFromStringProperty("lit", "", "lit_", fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v));
298
299 $this->slabIdInfix = new BoolFromStringProperty(
300 "double",
301 "",
302 "double_",
303 fn(Slab $b) => $b->getSlabType() === SlabType::DOUBLE,
304
305 //we don't know this is actually a bottom slab yet but we don't have enough information to set the
306 //correct type in this handler
307 //BOTTOM serves as a signal value for the state deserializer to decide whether to ignore the
308 //upper_block_bit property
309 fn(Slab $b, bool $v) => $b->setSlabType($v ? SlabType::DOUBLE : SlabType::BOTTOM)
310 );
311 $this->slabPositionProperty = new BoolFromStringProperty(
312 StateNames::MC_VERTICAL_HALF,
313 BlockStateStringValues::MC_VERTICAL_HALF_BOTTOM,
314 BlockStateStringValues::MC_VERTICAL_HALF_TOP,
315 fn(Slab $b) => $b->getSlabType() === SlabType::TOP,
316
317 //Ignore the value for double slabs (should be set by ID component before this is reached)
318 fn(Slab $b, bool $v) => $b->getSlabType() !== SlabType::DOUBLE ? $b->setSlabType($v ? SlabType::TOP : SlabType::BOTTOM) : null
319 );
320
321 $this->coralIdPrefixes = [
322 "minecraft:",
323 new BoolFromStringProperty("dead", "", "dead_", fn(CoralMaterial $b) => $b->isDead(), fn(CoralMaterial $b, bool $v) => $b->setDead($v)),
324 new ValueFromStringProperty("type", EnumFromRawStateMap::string(CoralType::class, fn(CoralType $case) => match ($case) {
325 CoralType::BRAIN => "brain",
326 CoralType::BUBBLE => "bubble",
327 CoralType::FIRE => "fire",
328 CoralType::HORN => "horn",
329 CoralType::TUBE => "tube"
330 }), fn(CoralMaterial $b) => $b->getCoralType(), fn(CoralMaterial $b, CoralType $v) => $b->setCoralType($v)),
331 ];
332 $this->copperIdPrefixes = [
333 "minecraft:",
334 new BoolFromStringProperty("waxed", "", "waxed_", fn(CopperMaterial $b) => $b->isWaxed(), fn(CopperMaterial $b, bool $v) => $b->setWaxed($v)),
335 new ValueFromStringProperty("oxidation", EnumFromRawStateMap::string(CopperOxidation::class, fn(CopperOxidation $case) => match ($case) {
336 CopperOxidation::NONE => "",
337 CopperOxidation::EXPOSED => "exposed_",
338 CopperOxidation::WEATHERED => "weathered_",
339 CopperOxidation::OXIDIZED => "oxidized_",
340 }), fn(CopperMaterial $b) => $b->getOxidation(), fn(CopperMaterial $b, CopperOxidation $v) => $b->setOxidation($v))
341 ];
342
343 $this->furnaceIdPrefixes = ["minecraft:", $this->litIdInfix];
344
345 $this->liquidIdPrefixes = [
346 "minecraft:",
347 new BoolFromStringProperty("still", "flowing_", "", fn(Liquid $b) => $b->isStill(), fn(Liquid $b, bool $v) => $b->setStill($v))
348 ];
349
350 $this->woodIdPrefixes = [
351 "minecraft:",
352 new BoolFromStringProperty("stripped", "", "stripped_", fn(Wood $b) => $b->isStripped(), fn(Wood $b, bool $v) => $b->setStripped($v)),
353 ];
354
355 $this->buttonProperties = [
357 new BoolProperty(StateNames::BUTTON_PRESSED_BIT, fn(Button $b) => $b->isPressed(), fn(Button $b, bool $v) => $b->setPressed($v)),
358 ];
359
360 $this->campfireProperties = [
362 new BoolProperty(StateNames::EXTINGUISHED, fn(Lightable $b) => $b->isLit(), fn(Lightable $b, bool $v) => $b->setLit($v), inverted: true),
363 ];
364
365 //TODO: check if these need any special treatment to get the appropriate data to both halves of the door
366 $this->doorProperties = [
367 new BoolProperty(StateNames::UPPER_BLOCK_BIT, fn(Door $b) => $b->isTop(), fn(Door $b, bool $v) => $b->setTop($v)),
368 new BoolProperty(StateNames::DOOR_HINGE_BIT, fn(Door $b) => $b->isHingeRight(), fn(Door $b, bool $v) => $b->setHingeRight($v)),
369 new BoolProperty(StateNames::OPEN_BIT, fn(Door $b) => $b->isOpen(), fn(Door $b, bool $v) => $b->setOpen($v)),
371 StateNames::MC_CARDINAL_DIRECTION,
372 EnumFromRawStateMap::string(HorizontalFacingOption::class, fn(HorizontalFacingOption $case) => match ($case) {
373 //a door facing "east" is actually facing north - thanks mojang
374 HorizontalFacingOption::NORTH => BlockStateStringValues::MC_CARDINAL_DIRECTION_EAST,
375 HorizontalFacingOption::EAST => BlockStateStringValues::MC_CARDINAL_DIRECTION_SOUTH,
376 HorizontalFacingOption::SOUTH => BlockStateStringValues::MC_CARDINAL_DIRECTION_WEST,
377 HorizontalFacingOption::WEST => BlockStateStringValues::MC_CARDINAL_DIRECTION_NORTH
378 }),
379 fn(HorizontalFacing $b) => $b->getFacing(),
380 fn(HorizontalFacing $b, HorizontalFacingOption $v) => $b->setFacing($v)
381 )
382 ];
383
384 $this->fenceGateProperties = [
385 new BoolProperty(StateNames::IN_WALL_BIT, fn(FenceGate $b) => $b->isInWall(), fn(FenceGate $b, bool $v) => $b->setInWall($v)),
386 new BoolProperty(StateNames::OPEN_BIT, fn(FenceGate $b) => $b->isOpen(), fn(FenceGate $b, bool $v) => $b->setOpen($v)),
388 ];
389
390 $this->itemFrameProperties = [
391 new DummyProperty(StateNames::ITEM_FRAME_PHOTO_BIT, false), //TODO: not sure what the point of this is
392 new BoolProperty(StateNames::ITEM_FRAME_MAP_BIT, fn(ItemFrame $b) => $b->hasMap(), fn(ItemFrame $b, bool $v) => $b->setHasMap($v)),
394 ];
395
396 $this->simplePressurePlateProperties = [
397 //TODO: not sure what the deal is here ... seems like a mojang bug / artifact of bad implementation?
398 //best to keep this separate from weighted plates anyway...
399 new IntProperty(
400 StateNames::REDSTONE_SIGNAL,
401 0,
402 15,
403 fn(SimplePressurePlate $b) => $b->isPressed() ? 15 : 0,
404 fn(SimplePressurePlate $b, int $v) => $b->setPressed($v !== 0)
405 )
406 ];
407
408 $this->stairProperties = [
409 new BoolProperty(StateNames::UPSIDE_DOWN_BIT, fn(Stair $b) => $b->isUpsideDown(), fn(Stair $b, bool $v) => $b->setUpsideDown($v)),
410 new ValueFromIntProperty(StateNames::WEIRDO_DIRECTION, $vm->horizontalFacing5Minus, $hfGet, $hfSet),
411 ];
412
413 $this->stemProperties = [
414 new ValueFromIntProperty(StateNames::FACING_DIRECTION, $vm->facingStem, fn(Stem $b) => $b->getFacing()->value, fn(Stem $b, int $v) => $b->setFacing(Facing::from($v))),
416 ];
417
418 $this->trapdoorProperties = [
419 //this uses the same values as stairs, but the state is named differently
420 new ValueFromIntProperty(StateNames::DIRECTION, $vm->horizontalFacing5Minus, $hfGet, $hfSet),
421
422 new BoolProperty(StateNames::UPSIDE_DOWN_BIT, fn(Trapdoor $b) => $b->isTop(), fn(Trapdoor $b, bool $v) => $b->setTop($v)),
423 new BoolProperty(StateNames::OPEN_BIT, fn(Trapdoor $b) => $b->isOpen(), fn(Trapdoor $b, bool $v) => $b->setOpen($v)),
424 ];
425
426 $wallProperties = [
427 new BoolProperty(StateNames::WALL_POST_BIT, fn(Wall $b) => $b->isPost(), fn(Wall $b, bool $v) => $b->setPost($v)),
428 ];
429 foreach([
430 [Facing::NORTH, StateNames::WALL_CONNECTION_TYPE_NORTH],
431 [Facing::SOUTH, StateNames::WALL_CONNECTION_TYPE_SOUTH],
432 [Facing::WEST, StateNames::WALL_CONNECTION_TYPE_WEST],
433 [Facing::EAST, StateNames::WALL_CONNECTION_TYPE_EAST]
434 ] as [$facing, $stateName]){
435 $wallProperties[] = new ValueFromStringProperty(
436 $stateName,
437 EnumFromRawStateMap::string(WallConnectionTypeShim::class, fn(WallConnectionTypeShim $case) => $case->getValue()),
438 fn(Wall $b) => WallConnectionTypeShim::serialize($b->getConnection($facing)),
439 fn(Wall $b, WallConnectionTypeShim $v) => $b->setConnection($facing, $v->deserialize())
440 );
441 }
442 $this->wallProperties = $wallProperties;
443 }
444}
setConnection(Facing $face, ?WallConnectionType $type)
Definition Wall.php:71
static string(string $class, \Closure $mapper, ?\Closure $aliasMapper=null)
static int(string $class, \Closure $mapper, ?\Closure $aliasMapper=null)
setFacing(HorizontalFacingOption $facing)