PocketMine-MP 5.32.2 git-237b304ef9858756b018e44e8f298093f66f823b
Loading...
Searching...
No Matches
BaseSign.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\block;
25
26use pocketmine\block\tile\Sign as TileSign;
27use pocketmine\block\utils\DyeColor;
29use pocketmine\block\utils\SupportType;
31use pocketmine\block\utils\WoodType;
32use pocketmine\block\utils\WoodTypeTrait;
44use function array_map;
45use function assert;
46use function strlen;
47
48abstract class BaseSign extends Transparent implements WoodMaterial{
49 use WoodTypeTrait;
50
51 protected SignText $text;
52 private bool $waxed = false;
53
54 protected ?int $editorEntityRuntimeId = null;
55
57 private \Closure $asItemCallback;
58
62 public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback){
63 $this->woodType = $woodType;
64 parent::__construct($idInfo, $name, $typeInfo);
65 $this->text = new SignText();
66 $this->asItemCallback = $asItemCallback;
67 }
68
69 public function readStateFromWorld() : Block{
70 parent::readStateFromWorld();
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();
76 }
77
78 return $this;
79 }
80
81 public function writeStateToWorld() : void{
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);
88 }
89
90 public function isSolid() : bool{
91 return false;
92 }
93
94 public function getMaxStackSize() : int{
95 return 16;
96 }
97
98 protected function recalculateCollisionBoxes() : array{
99 return [];
100 }
101
102 public function getSupportType(int $facing) : SupportType{
103 return SupportType::NONE;
104 }
105
106 abstract protected function getSupportingFace() : int;
107
108 public function onNearbyBlockChange() : void{
109 if($this->getSide($this->getSupportingFace())->getTypeId() === BlockTypeIds::AIR){
110 $this->position->getWorld()->useBreakOn($this->position);
111 }
112 }
113
114 public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
115 if($player !== null){
116 $this->editorEntityRuntimeId = $player->getId();
117 }
118 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
119 }
120
121 public function onPostPlace() : void{
122 $player = $this->editorEntityRuntimeId !== null ?
123 $this->position->getWorld()->getEntity($this->editorEntityRuntimeId) :
124 null;
125 if($player instanceof Player){
126 $player->openSignEditor($this->position);
127 }
128 }
129
130 private function doSignChange(SignText $newText, Player $player, Item $item) : bool{
131 $ev = new SignChangeEvent($this, $player, $newText);
132 $ev->call();
133 if(!$ev->isCancelled()){
134 $this->text = $ev->getNewText();
135 $this->position->getWorld()->setBlock($this->position, $this);
136 $item->pop();
137 return true;
138 }
139
140 return false;
141 }
142
143 private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{
144 if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
145 $this->position->getWorld()->addSound($this->position, new InkSacUseSound());
146 return true;
147 }
148 return false;
149 }
150
151 private function wax(Player $player, Item $item) : bool{
152 if($this->waxed){
153 return false;
154 }
155
156 $this->waxed = true;
157 $this->position->getWorld()->setBlock($this->position, $this);
158 $item->pop();
159
160 return true;
161 }
162
163 public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
164 if($player === null){
165 return false;
166 }
167 if($this->waxed){
168 return true;
169 }
170
171 $dyeColor = $item instanceof Dye ? $item->getColor() : match($item->getTypeId()){
172 ItemTypeIds::BONE_MEAL => DyeColor::WHITE,
173 ItemTypeIds::LAPIS_LAZULI => DyeColor::BLUE,
174 ItemTypeIds::COCOA_BEANS => DyeColor::BROWN,
175 default => null
176 };
177 if($dyeColor !== null){
178 $color = $dyeColor === DyeColor::BLACK ? new Color(0, 0, 0) : $dyeColor->getRgbValue();
179 if(
180 $color->toARGB() !== $this->text->getBaseColor()->toARGB() &&
181 $this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)
182 ){
183 $this->position->getWorld()->addSound($this->position, new DyeUseSound());
184 return true;
185 }
186 }elseif(match($item->getTypeId()){
187 ItemTypeIds::INK_SAC => $this->changeSignGlowingState(false, $player, $item),
188 ItemTypeIds::GLOW_INK_SAC => $this->changeSignGlowingState(true, $player, $item),
189 ItemTypeIds::HONEYCOMB => $this->wax($player, $item),
190 default => false
191 }){
192 return true;
193 }
194
195 $player->openSignEditor($this->position);
196
197 return true;
198 }
199
203 public function getText() : SignText{
204 return $this->text;
205 }
206
208 public function setText(SignText $text) : self{
209 $this->text = $text;
210 return $this;
211 }
212
216 public function isWaxed() : bool{ return $this->waxed; }
217
219 public function setWaxed(bool $waxed) : self{
220 $this->waxed = $waxed;
221 return $this;
222 }
223
229 public function getEditorEntityRuntimeId() : ?int{ return $this->editorEntityRuntimeId; }
230
232 public function setEditorEntityRuntimeId(?int $editorEntityRuntimeId) : self{
233 $this->editorEntityRuntimeId = $editorEntityRuntimeId;
234 return $this;
235 }
236
243 public function updateText(Player $author, SignText $text) : bool{
244 $size = 0;
245 foreach($text->getLines() as $line){
246 $size += strlen($line);
247 }
248 if($size > 1000){
249 throw new \UnexpectedValueException($author->getName() . " tried to write $size bytes of text onto a sign (bigger than max 1000)");
250 }
251 $ev = new SignChangeEvent($this, $author, new SignText(array_map(function(string $line) : string{
252 return TextFormat::clean($line, false);
253 }, $text->getLines()), $this->text->getBaseColor(), $this->text->isGlowing()));
254 if($this->waxed || $this->editorEntityRuntimeId !== $author->getId()){
255 $ev->cancel();
256 }
257 $ev->call();
258 if(!$ev->isCancelled()){
259 $this->setText($ev->getNewText());
260 $this->setEditorEntityRuntimeId(null);
261 $this->position->getWorld()->setBlock($this->position, $this);
262 return true;
263 }
264
265 return false;
266 }
267
268 public function asItem() : Item{
269 return ($this->asItemCallback)();
270 }
271
272 public function getFuelTime() : int{
273 return $this->woodType->isFlammable() ? 200 : 0;
274 }
275}
setEditorEntityRuntimeId(?int $editorEntityRuntimeId)
Definition BaseSign.php:232
updateText(Player $author, SignText $text)
Definition BaseSign.php:243
onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player=null, array &$returnedItems=[])
Definition BaseSign.php:163
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)
Definition BaseSign.php:114
getSupportType(int $facing)
Definition BaseSign.php:102
setText(SignText $text)
Definition BaseSign.php:208
__construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback)
Definition BaseSign.php:62