mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-01 17:53:41 +00:00
This is a similar refactor to the one I recently did for tiles. - Entity::createEntity() is removed. In its place are Entity::create() (runtime creation, use where you'd use a constructor, accepts a ::class parameter, throws exceptions on unknown entities) and Entity::createFromData() (internal, used to restore entities from chunks, swallows unknown entities and returns null). - Entity::registerEntity() is renamed to Entity::register(). - Added Entity::override() to allow overriding factory classes without touching save IDs. This allows more cleanly extending & overriding entities. This method only allows overriding registered Entity classes with children of that class, which makes code using the factory much more sane and allows to provide safety guarantees which make the code less nasty. - Entity::getKnownEntityTypes() is renamed to Entity::getKnownTypes(). - ProjectileItem::getProjectileEntityType() now returns a ::class constant instead of a stringy ID. - Cleaned up a bunch of nasty code, particularly in Bow.
105 lines
3.0 KiB
PHP
105 lines
3.0 KiB
PHP
<?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\item;
|
|
|
|
use pocketmine\block\Block;
|
|
use pocketmine\entity\Entity;
|
|
use pocketmine\entity\object\Painting;
|
|
use pocketmine\entity\object\PaintingMotive;
|
|
use pocketmine\math\Facing;
|
|
use pocketmine\math\Vector3;
|
|
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
|
use pocketmine\Player;
|
|
use function array_rand;
|
|
|
|
class PaintingItem extends Item{
|
|
public function __construct(){
|
|
parent::__construct(self::PAINTING, 0, "Painting");
|
|
}
|
|
|
|
public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{
|
|
if(Facing::axis($face) === Facing::AXIS_Y){
|
|
return false;
|
|
}
|
|
|
|
$motives = [];
|
|
|
|
$totalDimension = 0;
|
|
foreach(PaintingMotive::getAll() as $motive){
|
|
$currentTotalDimension = $motive->getHeight() + $motive->getWidth();
|
|
if($currentTotalDimension < $totalDimension){
|
|
continue;
|
|
}
|
|
|
|
if(Painting::canFit($player->getLevel(), $blockReplace, $face, true, $motive)){
|
|
if($currentTotalDimension > $totalDimension){
|
|
$totalDimension = $currentTotalDimension;
|
|
/*
|
|
* This drops all motive possibilities smaller than this
|
|
* We use the total of height + width to allow equal chance of horizontal/vertical paintings
|
|
* when there is an L-shape of space available.
|
|
*/
|
|
$motives = [];
|
|
}
|
|
|
|
$motives[] = $motive;
|
|
}
|
|
}
|
|
|
|
if(empty($motives)){ //No space available
|
|
return false;
|
|
}
|
|
|
|
/** @var PaintingMotive $motive */
|
|
$motive = $motives[array_rand($motives)];
|
|
|
|
static $directions = [
|
|
Facing::SOUTH => 0,
|
|
Facing::WEST => 1,
|
|
Facing::NORTH => 2,
|
|
Facing::EAST => 3
|
|
];
|
|
|
|
$direction = $directions[$face] ?? -1;
|
|
if($direction === -1){
|
|
return false;
|
|
}
|
|
|
|
$nbt = Entity::createBaseNBT($blockReplace, null, $direction * 90, 0);
|
|
$nbt->setByte("Direction", $direction);
|
|
$nbt->setString("Motive", $motive->getName());
|
|
$nbt->setInt("TileX", $blockClicked->getFloorX());
|
|
$nbt->setInt("TileY", $blockClicked->getFloorY());
|
|
$nbt->setInt("TileZ", $blockClicked->getFloorZ());
|
|
|
|
/** @var Painting $entity */
|
|
$entity = Entity::create(Painting::class, $blockReplace->getLevel(), $nbt);
|
|
$this->pop();
|
|
$entity->spawnToAll();
|
|
|
|
$player->getLevel()->broadcastLevelEvent($blockReplace->add(0.5, 0.5, 0.5), LevelEventPacket::EVENT_SOUND_ITEMFRAME_PLACE); //item frame and painting have the same sound
|
|
return true;
|
|
}
|
|
}
|