Fixed glowing item frames

due to technical limitations, this requires separating them back into two different block types. However, this isn't too egregious since it's just one flag, and actually simplifies some code.

closes #5478
This commit is contained in:
Dylan K. Taylor 2023-01-12 21:52:44 +00:00
parent 9c391a6809
commit ca1f1bf09f
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
12 changed files with 67 additions and 52 deletions

View File

@ -708,6 +708,7 @@ final class BlockTypeIds{
public const WEEPING_VINES = 10681;
public const CHAIN = 10682;
public const SCULK = 10683;
public const GLOWING_ITEM_FRAME = 10684;
public const FIRST_UNUSED_BLOCK_ID = 10684;

View File

@ -44,20 +44,12 @@ class ItemFrame extends Flowable{
public const ROTATIONS = 8;
protected bool $glowing = false;
protected bool $hasMap = false; //makes frame appear large if set
protected ?Item $framedItem = null;
protected int $itemRotation = 0;
protected float $itemDropChance = 1.0;
public function getRequiredTypeDataBits() : int{ return 1; }
protected function describeType(RuntimeDataReader|RuntimeDataWriter $w) : void{
$w->bool($this->glowing);
}
public function getRequiredStateDataBits() : int{ return 4; }
protected function describeState(RuntimeDataReader|RuntimeDataWriter $w) : void{
@ -141,14 +133,6 @@ class ItemFrame extends Flowable{
return $this;
}
public function isGlowing() : bool{ return $this->glowing; }
/** @return $this */
public function setGlowing(bool $glowing) : self{
$this->glowing = $glowing;
return $this;
}
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($this->framedItem !== null){
$this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS;

View File

@ -43,6 +43,7 @@ use pocketmine\block\tile\DaylightSensor as TileDaylightSensor;
use pocketmine\block\tile\EnchantTable as TileEnchantingTable;
use pocketmine\block\tile\EnderChest as TileEnderChest;
use pocketmine\block\tile\FlowerPot as TileFlowerPot;
use pocketmine\block\tile\GlowingItemFrame as TileGlowingItemFrame;
use pocketmine\block\tile\Hopper as TileHopper;
use pocketmine\block\tile\ItemFrame as TileItemFrame;
use pocketmine\block\tile\Jukebox as TileJukebox;
@ -409,6 +410,7 @@ use function mb_strtolower;
* @method static Glass GLASS()
* @method static GlassPane GLASS_PANE()
* @method static GlazedTerracotta GLAZED_TERRACOTTA()
* @method static ItemFrame GLOWING_ITEM_FRAME()
* @method static GlowingObsidian GLOWING_OBSIDIAN()
* @method static Glowstone GLOWSTONE()
* @method static Opaque GOLD()
@ -886,7 +888,11 @@ final class VanillaBlocks{
$ironDoorBreakInfo = new Info(BreakInfo::pickaxe(5.0, ToolTier::WOOD(), 25.0));
self::register("iron_door", new Door(new BID(Ids::IRON_DOOR), "Iron Door", $ironDoorBreakInfo));
self::register("iron_trapdoor", new Trapdoor(new BID(Ids::IRON_TRAPDOOR), "Iron Trapdoor", $ironDoorBreakInfo));
self::register("item_frame", new ItemFrame(new BID(Ids::ITEM_FRAME, TileItemFrame::class), "Item Frame", new Info(new BreakInfo(0.25))));
$itemFrameInfo = new Info(new BreakInfo(0.25));
self::register("item_frame", new ItemFrame(new BID(Ids::ITEM_FRAME, TileItemFrame::class), "Item Frame", $itemFrameInfo));
self::register("glowing_item_frame", new ItemFrame(new BID(Ids::GLOWING_ITEM_FRAME, TileGlowingItemFrame::class), "Glow Item Frame", $itemFrameInfo));
self::register("jukebox", new Jukebox(new BID(Ids::JUKEBOX, TileJukebox::class), "Jukebox", new Info(BreakInfo::axe(0.8)))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not
self::register("ladder", new Ladder(new BID(Ids::LADDER), "Ladder", new Info(BreakInfo::axe(0.4))));

View File

@ -0,0 +1,32 @@
<?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\tile;
/**
* @deprecated
* @see \pocketmine\block\ItemFrame
*/
final class GlowingItemFrame extends ItemFrame{
}

View File

@ -76,6 +76,7 @@ final class TileFactory{
$this->register(Smoker::class, ["Smoker", "minecraft:smoker"]);
$this->register(SporeBlossom::class, ["SporeBlossom", "minecraft:spore_blossom"]);
$this->register(Skull::class, ["Skull", "minecraft:skull"]);
$this->register(GlowingItemFrame::class, ["GlowItemFrame"]);
//TODO: Campfire
//TODO: ChalkboardBlock

View File

@ -990,6 +990,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
})
->writeHorizontalFacing($block->getFacing());
});
$this->map(Blocks::GLOWING_ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::GLOW_FRAME));
$this->map(Blocks::GRANITE(), fn() => Helper::encodeStone(StringValues::STONE_TYPE_GRANITE));
$this->map(Blocks::GRANITE_SLAB(), fn(Slab $block) => Helper::encodeStoneSlab3($block, StringValues::STONE_SLAB_TYPE_3_GRANITE));
$this->mapStairs(Blocks::GRANITE_STAIRS(), Ids::GRANITE_STAIRS);
@ -1019,12 +1020,7 @@ final class BlockObjectToStateSerializer implements BlockStateSerializer{
->writeString(StateNames::MONSTER_EGG_STONE_TYPE, StringValues::MONSTER_EGG_STONE_TYPE_STONE_BRICK));
$this->map(Blocks::IRON_DOOR(), fn(Door $block) => Helper::encodeDoor($block, new Writer(Ids::IRON_DOOR)));
$this->map(Blocks::IRON_TRAPDOOR(), fn(Trapdoor $block) => Helper::encodeTrapdoor($block, new Writer(Ids::IRON_TRAPDOOR)));
$this->map(Blocks::ITEM_FRAME(), function(ItemFrame $block) : Writer{
return Writer::create($block->isGlowing() ? Ids::GLOW_FRAME : Ids::FRAME)
->writeBool(StateNames::ITEM_FRAME_MAP_BIT, $block->hasMap())
->writeBool(StateNames::ITEM_FRAME_PHOTO_BIT, false)
->writeFacingDirection($block->getFacing());
});
$this->map(Blocks::ITEM_FRAME(), fn(ItemFrame $block) => Helper::encodeItemFrame($block, Ids::FRAME));
$this->map(Blocks::JUNGLE_BUTTON(), fn(WoodenButton $block) => Helper::encodeButton($block, new Writer(Ids::JUNGLE_BUTTON)));
$this->map(Blocks::JUNGLE_DOOR(), fn(WoodenDoor $block) => Helper::encodeDoor($block, new Writer(Ids::JUNGLE_DOOR)));
$this->map(Blocks::JUNGLE_FENCE(), fn() => Writer::create(Ids::FENCE)

View File

@ -49,7 +49,6 @@ use pocketmine\block\Trapdoor;
use pocketmine\block\utils\CopperOxidation;
use pocketmine\block\utils\DyeColor;
use pocketmine\block\VanillaBlocks;
use pocketmine\block\VanillaBlocks as Blocks;
use pocketmine\block\Wall;
use pocketmine\block\WallCoralFan;
use pocketmine\block\WallSign;
@ -172,12 +171,11 @@ final class BlockStateDeserializerHelper{
->setFacing($in->readHorizontalFacing());
}
public static function decodeItemFrame(BlockStateReader $in, bool $glowing) : ItemFrame{
public static function decodeItemFrame(ItemFrame $block, BlockStateReader $in) : ItemFrame{
$in->todo(StateNames::ITEM_FRAME_PHOTO_BIT); //TODO: not sure what the point of this is
return Blocks::ITEM_FRAME()
return $block
->setFacing($in->readFacingDirection())
->setHasMap($in->readBool(StateNames::ITEM_FRAME_MAP_BIT))
->setGlowing($glowing);
->setHasMap($in->readBool(StateNames::ITEM_FRAME_MAP_BIT));
}
/** @throws BlockStateDeserializeException */

View File

@ -32,6 +32,7 @@ use pocketmine\block\DoublePlant;
use pocketmine\block\FenceGate;
use pocketmine\block\FloorSign;
use pocketmine\block\Furnace;
use pocketmine\block\ItemFrame;
use pocketmine\block\Leaves;
use pocketmine\block\Liquid;
use pocketmine\block\RedMushroomBlock;
@ -50,6 +51,7 @@ use pocketmine\block\Wood;
use pocketmine\data\bedrock\block\BlockStateNames;
use pocketmine\data\bedrock\block\BlockStateNames as StateNames;
use pocketmine\data\bedrock\block\BlockTypeNames as Ids;
use pocketmine\data\bedrock\block\convert\BlockStateWriter as Writer;
use pocketmine\data\bedrock\MushroomBlockTypeIdMap;
use pocketmine\math\Facing;
use pocketmine\utils\AssumptionFailedError;
@ -138,6 +140,13 @@ final class BlockStateSerializerHelper{
->writeHorizontalFacing($block->getFacing());
}
public static function encodeItemFrame(ItemFrame $block, string $id) : BlockStateWriter{
return Writer::create($id)
->writeBool(StateNames::ITEM_FRAME_MAP_BIT, $block->hasMap())
->writeBool(StateNames::ITEM_FRAME_PHOTO_BIT, false)
->writeFacingDirection($block->getFacing());
}
private static function encodeLeaves(Leaves $block, BlockStateWriter $out) : BlockStateWriter{
return $out
->writeBool(BlockStateNames::PERSISTENT_BIT, $block->isNoDecay())

View File

@ -731,7 +731,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
});
$this->map(Ids::FLOWING_LAVA, fn(Reader $in) => Helper::decodeFlowingLiquid(Blocks::LAVA(), $in));
$this->map(Ids::FLOWING_WATER, fn(Reader $in) => Helper::decodeFlowingLiquid(Blocks::WATER(), $in));
$this->map(Ids::FRAME, fn(Reader $in) => Helper::decodeItemFrame($in, false));
$this->map(Ids::FRAME, fn(Reader $in) => Helper::decodeItemFrame(Blocks::ITEM_FRAME(), $in));
$this->map(Ids::FROSTED_ICE, function(Reader $in) : Block{
return Blocks::FROSTED_ICE()
->setAge($in->readBoundedInt(StateNames::AGE, 0, 3));
@ -741,7 +741,7 @@ final class BlockStateToObjectDeserializer implements BlockStateDeserializer{
->setFacing($in->readHorizontalFacing())
->setLit(false);
});
$this->map(Ids::GLOW_FRAME, fn(Reader $in) => Helper::decodeItemFrame($in, true));
$this->map(Ids::GLOW_FRAME, fn(Reader $in) => Helper::decodeItemFrame(Blocks::GLOWING_ITEM_FRAME(), $in));
$this->map(Ids::GOLDEN_RAIL, function(Reader $in) : Block{
return Blocks::POWERED_RAIL()
->setPowered($in->readBool(StateNames::RAIL_DATA_BIT))

View File

@ -25,7 +25,6 @@ namespace pocketmine\data\bedrock\item;
use pocketmine\block\Bed;
use pocketmine\block\Block;
use pocketmine\block\ItemFrame;
use pocketmine\block\Skull;
use pocketmine\block\utils\DyeColor;
use pocketmine\block\utils\SkullType;
@ -57,7 +56,6 @@ final class ItemSerializerDeserializerRegistrar{
$this->register1to1BlockWithMetaMappings();
$this->register1to1ItemWithMetaMappings();
$this->register1ToNItemMappings();
$this->registerMiscBlockMappings();
$this->registerMiscItemMappings();
}
@ -141,6 +139,8 @@ final class ItemSerializerDeserializerRegistrar{
$this->map1to1Block(Ids::CRIMSON_DOOR, Blocks::CRIMSON_DOOR());
$this->map1to1Block(Ids::DARK_OAK_DOOR, Blocks::DARK_OAK_DOOR());
$this->map1to1Block(Ids::FLOWER_POT, Blocks::FLOWER_POT());
$this->map1to1Block(Ids::FRAME, Blocks::ITEM_FRAME());
$this->map1to1Block(Ids::GLOW_FRAME, Blocks::GLOWING_ITEM_FRAME());
$this->map1to1Block(Ids::HOPPER, Blocks::HOPPER());
$this->map1to1Block(Ids::IRON_DOOR, Blocks::IRON_DOOR());
$this->map1to1Block(Ids::JUNGLE_DOOR, Blocks::JUNGLE_DOOR());
@ -502,19 +502,6 @@ final class ItemSerializerDeserializerRegistrar{
);
}
/**
* Registers serializers and deserializers for blocks that don't fit any other pattern.
* Ideally we want to get rid of this completely, if possible.
*
* Most of these are single PocketMine-MP items which map to multiple IDs depending on their properties, which is
* complex to implement in a generic way.
*/
private function registerMiscBlockMappings() : void{
$this->deserializer?->mapBlock(Ids::FRAME, fn() => Blocks::ITEM_FRAME()->setGlowing(false));
$this->deserializer?->mapBlock(Ids::GLOW_FRAME, fn() => Blocks::ITEM_FRAME()->setGlowing(true));
$this->serializer?->mapBlock(Blocks::ITEM_FRAME(), fn(ItemFrame $block) => new Data($block->isGlowing() ? Ids::GLOW_FRAME : Ids::FRAME));
}
/**
* Registers serializers and deserializers for items that don't fit any other pattern.
* Ideally we want to get rid of this completely, if possible.

View File

@ -627,8 +627,8 @@ final class StringToItemParser extends StringToTParser{
$result->registerBlock("flower_pot_block", fn() => Blocks::FLOWER_POT());
$result->registerBlock("flowing_lava", fn() => Blocks::LAVA());
$result->registerBlock("flowing_water", fn() => Blocks::WATER());
$result->registerBlock("frame", fn() => Blocks::ITEM_FRAME()->setGlowing(false));
$result->registerBlock("frame_block", fn() => Blocks::ITEM_FRAME()->setGlowing(false));
$result->registerBlock("frame", fn() => Blocks::ITEM_FRAME());
$result->registerBlock("frame_block", fn() => Blocks::ITEM_FRAME());
$result->registerBlock("frosted_ice", fn() => Blocks::FROSTED_ICE());
$result->registerBlock("furnace", fn() => Blocks::FURNACE());
$result->registerBlock("gilded_blackstone", fn() => Blocks::GILDED_BLACKSTONE());
@ -636,8 +636,9 @@ final class StringToItemParser extends StringToTParser{
$result->registerBlock("glass_pane", fn() => Blocks::GLASS_PANE());
$result->registerBlock("glass_panel", fn() => Blocks::GLASS_PANE());
$result->registerBlock("glazed_terracotta", fn() => Blocks::GLAZED_TERRACOTTA());
$result->registerBlock("glow_frame", fn() => Blocks::ITEM_FRAME()->setGlowing(true));
$result->registerBlock("glow_item_frame", fn() => Blocks::ITEM_FRAME()->setGlowing(true));
$result->registerBlock("glow_frame", fn() => Blocks::GLOWING_ITEM_FRAME());
$result->registerBlock("glow_item_frame", fn() => Blocks::GLOWING_ITEM_FRAME());
$result->registerBlock("glowing_item_frame", fn() => Blocks::GLOWING_ITEM_FRAME());
$result->registerBlock("glowing_obsidian", fn() => Blocks::GLOWING_OBSIDIAN());
$result->registerBlock("glowing_redstone_ore", fn() => Blocks::REDSTONE_ORE()->setLit(true));
$result->registerBlock("glowingobsidian", fn() => Blocks::GLOWING_OBSIDIAN());
@ -693,8 +694,8 @@ final class StringToItemParser extends StringToTParser{
$result->registerBlock("iron_ore", fn() => Blocks::IRON_ORE());
$result->registerBlock("iron_pressure_plate", fn() => Blocks::WEIGHTED_PRESSURE_PLATE_HEAVY());
$result->registerBlock("iron_trapdoor", fn() => Blocks::IRON_TRAPDOOR());
$result->registerBlock("item_frame", fn() => Blocks::ITEM_FRAME()->setGlowing(false));
$result->registerBlock("item_frame_block", fn() => Blocks::ITEM_FRAME()->setGlowing(false));
$result->registerBlock("item_frame", fn() => Blocks::ITEM_FRAME());
$result->registerBlock("item_frame_block", fn() => Blocks::ITEM_FRAME());
$result->registerBlock("jack_o_lantern", fn() => Blocks::LIT_PUMPKIN());
$result->registerBlock("jukebox", fn() => Blocks::JUKEBOX());
$result->registerBlock("jungle_button", fn() => Blocks::JUNGLE_BUTTON());

File diff suppressed because one or more lines are too long