22declare(strict_types=1);
27use pocketmine\block\utils\DyeColor;
29use pocketmine\block\utils\SupportType;
30use pocketmine\block\utils\WoodType;
31use pocketmine\block\utils\WoodTypeTrait;
44use
function array_map;
52 private bool $waxed =
false;
54 protected ?
int $editorEntityRuntimeId =
null;
57 private \Closure $asItemCallback;
63 $this->woodType = $woodType;
64 parent::__construct($idInfo, $name, $typeInfo);
66 $this->asItemCallback = $asItemCallback;
71 $tile = $this->position->getWorld()->getTile($this->position);
72 if($tile instanceof TileSign){
73 $this->text = $tile->getText();
74 $this->waxed = $tile->isWaxed();
75 $this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId();
82 parent::writeStateToWorld();
83 $tile = $this->position->getWorld()->getTile($this->position);
84 assert($tile instanceof TileSign);
85 $tile->setText($this->text);
86 $tile->setWaxed($this->waxed);
87 $tile->setEditorEntityRuntimeId($this->editorEntityRuntimeId);
106 return SupportType::NONE;
109 abstract protected function getSupportingFace() : int;
112 if($this->getSide($this->getSupportingFace())->getTypeId() ===
BlockTypeIds::AIR){
113 $this->position->getWorld()->useBreakOn($this->position);
118 if($player !== null){
119 $this->editorEntityRuntimeId = $player->getId();
121 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
125 $player = $this->editorEntityRuntimeId !== null ?
126 $this->position->getWorld()->getEntity($this->editorEntityRuntimeId) :
128 if($player instanceof
Player){
129 $player->openSignEditor($this->position);
133 private function doSignChange(SignText $newText,
Player $player, Item $item) : bool{
134 $ev = new SignChangeEvent($this, $player, $newText);
136 if(!$ev->isCancelled()){
137 $this->text = $ev->getNewText();
138 $this->position->getWorld()->setBlock($this->position, $this);
146 private function changeSignGlowingState(
bool $glowing, Player $player, Item $item) : bool{
147 if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
148 $this->position->getWorld()->addSound($this->position,
new InkSacUseSound());
154 private function wax(Player $player, Item $item) : bool{
160 $this->position->getWorld()->setBlock($this->position, $this);
167 if($player === null){
174 $dyeColor = $item instanceof Dye ? $item->getColor() : match($item->getTypeId()){
175 ItemTypeIds::BONE_MEAL => DyeColor::WHITE,
176 ItemTypeIds::LAPIS_LAZULI => DyeColor::BLUE,
177 ItemTypeIds::COCOA_BEANS => DyeColor::BROWN,
180 if($dyeColor !==
null){
181 $color = $dyeColor === DyeColor::BLACK ?
new Color(0, 0, 0) : $dyeColor->getRgbValue();
183 $color->toARGB() !== $this->text->getBaseColor()->toARGB() &&
184 $this->doSignChange(
new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)
186 $this->position->getWorld()->addSound($this->position,
new DyeUseSound());
189 }elseif(match($item->getTypeId()){
190 ItemTypeIds::INK_SAC => $this->changeSignGlowingState(false, $player, $item),
191 ItemTypeIds::GLOW_INK_SAC => $this->changeSignGlowingState(true, $player, $item),
192 ItemTypeIds::HONEYCOMB => $this->wax($player, $item),
198 $player->openSignEditor($this->position);
219 public function isWaxed() : bool{ return $this->waxed; }
223 $this->waxed = $waxed;
236 $this->editorEntityRuntimeId = $editorEntityRuntimeId;
248 foreach($text->
getLines() as $line){
249 $size += strlen($line);
252 throw new \UnexpectedValueException($author->
getName() .
" tried to write $size bytes of text onto a sign (bigger than max 1000)");
254 $ev =
new SignChangeEvent($this, $author,
new SignText(array_map(
function(
string $line) :
string{
255 return TextFormat::clean($line,
false);
256 }, $text->
getLines()), $this->text->getBaseColor(), $this->text->isGlowing()));
257 if($this->waxed || $this->editorEntityRuntimeId !== $author->getId()){
261 if(!$ev->isCancelled()){
262 $this->setText($ev->getNewText());
263 $this->setEditorEntityRuntimeId(
null);
264 $this->position->getWorld()->setBlock($this->position, $this);
272 return ($this->asItemCallback)();
276 return $this->woodType->isFlammable() ? 200 : 0;
setEditorEntityRuntimeId(?int $editorEntityRuntimeId)
updateText(Player $author, SignText $text)
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
recalculateCollisionBoxes()
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
getEditorEntityRuntimeId()
getSupportType(int $facing)
__construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback)