Написал плагин на хранилища испытаний. Проблема в том, что левитирующий текст над ними не отображается. Если что я только начал изучать php и pocketmine! Это один из моих первых плагинов. Не засирайте плз. Вот код:
<?php
namespace TrialKey;
use pocketmine\block\Block;
use pocketmine\event\Listener;
use pocketmine\event\player\PlayerInteractEvent;
use pocketmine\item\StringToItemParser;
use pocketmine\item\VanillaItems;
use pocketmine\world\Position;
use pocketmine\scheduler\Task;
use pocketmine\player\Player;
use pocketmine\plugin\PluginBase;
use pocketmine\utils\Config;
use pocketmine\world\particle\FloatingTextParticle;
use pocketmine\math\Vector3;
use pocketmine\utils\TextFormat;
class Main extends PluginBase implements Listener {
private Config $storageConfig;
private array $storagePositions = [];
private array $cooldowns = [];
private array $textParticles = [];
private ?int $updateTaskId = null;
protected function onEnable(): void {
$this->getServer()->getPluginManager()->registerEvents($this, $this);
// Создаем/загружаем конфиг с позициями хранилищ
$this->storageConfig = new Config($this->getDataFolder() . "storages.yml", Config::YAML);
$this->storagePositions = $this->storageConfig->getAll();
foreach ($this->storagePositions as $posStr => $particle) {
$this->createFloatingText($posStr);
}
$this->getScheduler()->scheduleRepeatingTask(new class($this) extends Task {
private Main $plugin;
public function __construct(Main $plugin) {
$this->plugin = $plugin;
}
public function onRun(): void {
$this->plugin->updateAllFloatingTexts();
}
}, 20); // 20 тиков = 1 секунда
}
public function updateAllFloatingTexts(): void {
foreach ($this->textParticles as $posStr => $particle) {
$this->updateFloatingText($posStr);
}
}
private function getCooldownText(string $posStr): string {
if (isset($this->cooldowns[$posStr])) {
$remaining = $this->cooldowns[$posStr] - time();
if ($remaining > 0) {
return TextFormat::YELLOW . "Доступно через: " . $remaining . " сек";
}
}
return TextFormat::GREEN . "Доступно сейчас";
}
protected function onDisable(): void {
// Сохраняем позиции хранилищ при выключении
$this->storageConfig->setAll($this->storagePositions);
$this->storageConfig->save();
}
private function createFloatingText(string $posStr): void {
$pos = $this->stringToBlockPos($posStr);
$this->getServer()->getWorldManager()->loadWorld("test");
$world = $this->getServer()->getWorldManager()->getWorldByName("test");
$vector = new Position($pos['x'], $pos['y'] + 1.5, $pos['z'], $world);
$text = TextFormat::BOLD . TextFormat::GOLD . "ХРАНИЛИЩЕ ИСПЫТАНИЙ\n" . TextFormat::RESET;
$text .= $this->getCooldownText($posStr);
$this->textParticles[$posStr] = new FloatingTextParticle($text, "");
$world->addParticle($vector, $this->textParticles[$posStr]);
}
private function updateFloatingText(string $posStr): void {
$text = TextFormat::BOLD . TextFormat::GOLD . "ХРАНИЛИЩЕ ИСПЫТАНИЙ\n" . TextFormat::RESET;
if (isset($this->cooldowns[$posStr])) {
$remaining = $this->cooldowns[$posStr] - time();
if ($remaining > 0) {
$text .= TextFormat::YELLOW . "Доступно через: " . $remaining . " сек";
$this->textParticles[$posStr]->setText($text);
$this->textParticles[$posStr]->setInvisible(false);
return;
}
// Удаляем кулдаун если время истекло
unset($this->cooldowns[$posStr]);
}
$text .= TextFormat::GREEN . "Доступно сейчас";
$this->textParticles[$posStr]->setText($text);
$this->textParticles[$posStr]->setInvisible(false);
}
public function onInteract(PlayerInteractEvent $event): void {
$player = $event->getPlayer();
$block = $event->getBlock();
$item = $event->getItem();
$blockPos = $this->blockToString($block);
//if ($player->hasPermission("trialkey.admin")) {
//$player->sendMessage("Вторая стадия!");
// Если оператор - устанавливаем/удаляем хранилище
//if (isset($this->storagePositions[$blockPos])) {
//unset($this->storagePositions[$blockPos]);
//$player->sendMessage("§aХранилище удалено с этой позиции");
//} else {
//$player->sendMessage("Третья стадия!");
//$this->storagePositions[$blockPos] = true;
//$player->sendMessage("§aХранилище установлено на этой позиции");
//}
//$event->cancel();
//return;
//}
// Проверяем, что игрок нажал ПКМ по хранилищу
if (isset($this->storagePositions[$blockPos])) {
// Проверяем наличие ключа
if (isset($this->cooldowns[$blockPos]) && ($remaining = $this->cooldowns[$blockPos] - time()) > 0) {
$player->sendMessage("§cЭто хранилище можно открыть через §e" . $remaining . "§c секунд");
$event->cancel();
return;
}
$trialKey = StringToItemParser::getInstance()->parse("trial_key");
$inventory = $player->getInventory();
$item = $event->getItem();
if ($item->equals($trialKey, false, false)) {
$inventory->removeItem($item->setCount(1));
$this->openStorage($player);
$this->cooldowns[$blockPos] = time() + 60;
$this->updateFloatingText($blockPos);
$event->cancel();
} else {
$player->sendMessage("§cДля открытия хранилища вам нужно держать ключ испытаний в руке!");
}
}
}
private function openStorage(Player $player): void {
$reward = match(mt_rand(1, 3)) {
1 => VanillaItems::DIAMOND()->setCount(3),
2 => VanillaItems::NETHERITE_HELMET(),
3 => VanillaItems::TOTEM(),
default => VanillaItems::DIAMOND()->setCount(1)
};
$player->getInventory()->addItem($reward);
$player->sendMessage("§aВы получили награду: " . $reward->getName());
}
private function stringToBlockPos(string $posStr): array {
$parts = explode(":", $posStr);
return [
'x' => (int)$parts[0],
'y' => (int)$parts[1],
'z' => (int)$parts[2],
'world' => $parts[3]
];
}
private function blockToString(Block $block): string {
return $block->getPosition()->getFloorX() . ":" .
$block->getPosition()->getFloorY() . ":" .
$block->getPosition()->getFloorZ() . ":" .
$block->getPosition()->getWorld()->getFolderName();
}
}