mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 10:53:05 +00:00
Implemented Paintings (#2073)
This supports vanilla placement of paintings, with overlap and collision checking. Paintings are removed when a block is placed inside them or if any of their supporting blocks are removed. As per vanilla, a random painting is chosen from the largest subset that will fit into the given space.
This commit is contained in:
@ -105,7 +105,7 @@ class ItemFactory{
|
||||
self::registerItem(new Item(Item::FLINT, 0, "Flint"));
|
||||
self::registerItem(new RawPorkchop());
|
||||
self::registerItem(new CookedPorkchop());
|
||||
self::registerItem(new Painting());
|
||||
self::registerItem(new PaintingItem());
|
||||
self::registerItem(new GoldenApple());
|
||||
self::registerItem(new Sign());
|
||||
self::registerItem(new ItemBlock(Block::OAK_DOOR_BLOCK, 0, Item::OAK_DOOR));
|
||||
|
@ -1,94 +0,0 @@
|
||||
<?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\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Painting extends Item{
|
||||
public function __construct(int $meta = 0){
|
||||
parent::__construct(self::PAINTING, $meta, "Painting");
|
||||
}
|
||||
|
||||
public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{
|
||||
if($blockClicked->isTransparent() === false and $face > 1 and $blockReplace->isSolid() === false){
|
||||
$faces = [
|
||||
2 => 1,
|
||||
3 => 3,
|
||||
4 => 0,
|
||||
5 => 2,
|
||||
|
||||
];
|
||||
$motives = [
|
||||
// Motive Width Height
|
||||
["Kebab", 1, 1],
|
||||
["Aztec", 1, 1],
|
||||
["Alban", 1, 1],
|
||||
["Aztec2", 1, 1],
|
||||
["Bomb", 1, 1],
|
||||
["Plant", 1, 1],
|
||||
["Wasteland", 1, 1],
|
||||
["Wanderer", 1, 2],
|
||||
["Graham", 1, 2],
|
||||
["Pool", 2, 1],
|
||||
["Courbet", 2, 1],
|
||||
["Sunset", 2, 1],
|
||||
["Sea", 2, 1],
|
||||
["Creebet", 2, 1],
|
||||
["Match", 2, 2],
|
||||
["Bust", 2, 2],
|
||||
["Stage", 2, 2],
|
||||
["Void", 2, 2],
|
||||
["SkullAndRoses", 2, 2],
|
||||
//array("Wither", 2, 2),
|
||||
["Fighters", 4, 2],
|
||||
["Skeleton", 4, 3],
|
||||
["DonkeyKong", 4, 3],
|
||||
["Pointer", 4, 4],
|
||||
["Pigscene", 4, 4],
|
||||
["Flaming Skull", 4, 4],
|
||||
];
|
||||
$motive = $motives[mt_rand(0, count($motives) - 1)];
|
||||
$data = [
|
||||
"x" => $blockClicked->x,
|
||||
"y" => $blockClicked->y,
|
||||
"z" => $blockClicked->z,
|
||||
"yaw" => $faces[$face] * 90,
|
||||
"Motive" => $motive[0],
|
||||
];
|
||||
//TODO
|
||||
//$e = $server->api->entity->add($level, ENTITY_OBJECT, OBJECT_PAINTING, $data);
|
||||
//$e->spawnToAll();
|
||||
/*if(($player->gamemode & 0x01) === 0x00){
|
||||
$player->removeItem(Item::get($this->getId(), $this->getDamage(), 1));
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
105
src/pocketmine/item/PaintingItem.php
Normal file
105
src/pocketmine/item/PaintingItem.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?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\Vector3;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class PaintingItem extends Item{
|
||||
public function __construct(int $meta = 0){
|
||||
parent::__construct(self::PAINTING, $meta, "Painting");
|
||||
}
|
||||
|
||||
public function onActivate(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : bool{
|
||||
if(!$blockClicked->isTransparent() and $face > 1 and !$blockReplace->isSolid()){
|
||||
/** @var PaintingMotive[] $motives */
|
||||
$motives = [];
|
||||
|
||||
$totalDimension = 0;
|
||||
foreach(PaintingMotive::getAll() as $motive){
|
||||
$currentTotalDimension = $motive->getHeight() + $motive->getWidth();
|
||||
if($currentTotalDimension < $totalDimension){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(Painting::canFit($player->level, $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 = [
|
||||
Vector3::SIDE_SOUTH => 0,
|
||||
Vector3::SIDE_WEST => 1,
|
||||
Vector3::SIDE_NORTH => 2,
|
||||
Vector3::SIDE_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());
|
||||
|
||||
$entity = Entity::createEntity("Painting", $blockReplace->getLevel(), $nbt);
|
||||
|
||||
if($entity instanceof Entity){
|
||||
--$this->count;
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user