Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block: (Walls) implement tall/short connections #6624

Open
wants to merge 3 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 112 additions & 37 deletions src/block/Wall.php
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
<?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\block;

use pocketmine\block\utils\SlabType;
use pocketmine\block\utils\SupportType;
use pocketmine\block\utils\WallConnectionType;
use pocketmine\data\runtime\RuntimeDataDescriber;
Expand Down Expand Up @@ -89,36 +71,129 @@
}

public function onNearbyBlockChange() : void{
if($this->recalculateConnections()){
$connectionsUpdated = $this->recalculateConnections();
$postUpdated = $this->recalculatePost();
if($connectionsUpdated || $postUpdated){
$this->position->getWorld()->setBlock($this->position, $this);
}
}

protected function recalculateConnections() : bool{
$changed = 0;
$updated = false;
$above = $this->getSide(Facing::UP);
$abovePos = $above->getPosition();

foreach(Facing::HORIZONTAL as $face) {
$side = $this->getSide($face);
$sidePos = $side->getPosition();

// TODO: Improve stair check by checking corners

$connected = match (get_class($side)) {
Cake::class => false,
Campfire::class => Facing::opposite($face) === Facing::DOWN,
Fence::class => Facing::opposite($face) === Facing::DOWN || Facing::opposite($face) === Facing::UP,
Hopper::class => Facing::opposite($face) === Facing::UP,
Slab::class => $side->getSlabType() === SlabType::DOUBLE || ($side->getSlabType() === SlabType::TOP && Facing::opposite($face) === Facing::UP) || Facing::opposite($face) === Facing::DOWN,
Stair::class => (!$side->isUpsideDown() && Facing::opposite($face) === Facing::DOWN) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way, there has to be a better way than hardcoding logic for every block...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The supportType can probably be used here (juste the idea, i don't have checked)

($side->isUpsideDown() && Facing::opposite($face) === Facing::UP) ||
in_array($face, [Facing::rotate($face, Axis::Y, false), $side->getFacing()]),

Check failure on line 100 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Call to function in_array() requires parameter #3 to be set.

Check failure on line 100 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Call to function in_array() requires parameter #3 to be set.

Check failure on line 100 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Call to function in_array() requires parameter #3 to be set.
default => !$side->isTransparent()
};

if (!$connected){
if($side instanceof Wall || $side instanceof Thin) $connected = true;
if($side instanceof FenceGate && $side->getFacing() === $face) $connected = true;
}
Comment on lines +104 to +107
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all in one if can be done here


//TODO: implement tall/short connections - right now we only support short as per pre-1.16
$connectionType = null;
if ($connected) {
$connectionType = WallConnectionType::SHORT();

Check failure on line 111 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().

Check failure on line 111 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().

Check failure on line 111 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().
$boxes = $above->recalculateCollisionBoxes();

foreach($boxes as $bb) {
if ($bb->minY == 0) {

Check failure on line 115 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Loose comparison via "==" is not allowed.

Check failure on line 115 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Loose comparison via "==" is not allowed.

Check failure on line 115 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Loose comparison via "==" is not allowed.
$xOverlap = $bb->minX < 0.75 && $bb->maxX > 0.25;
$zOverlap = $bb->minX < 0.75 && $bb->maxX > 0.25;

$tall = match($face) {
Facing::NORTH => $xOverlap && $bb->maxZ > 0.75,
Facing::EAST => $bb->minX < 0.25 && $zOverlap,
Facing::SOUTH => $xOverlap && $bb->minZ < 0.25,
Facing::WEST => $bb->maxX > 0.75 && $zOverlap,

Check failure on line 123 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Match arm comparison between 4 and 4 is always true.

Check failure on line 123 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Match arm comparison between 4 and 4 is always true.

Check failure on line 123 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Match arm comparison between 4 and 4 is always true.
default => false
};
if ($tall) {
$connectionType = WallConnectionType::TALL();

Check failure on line 127 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().

Check failure on line 127 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().

Check failure on line 127 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().
}
}
}
}

foreach(Facing::HORIZONTAL as $facing){
$block = $this->getSide($facing);
if($block instanceof static || $block instanceof FenceGate || $block instanceof Thin || $block->getSupportType(Facing::opposite($facing)) === SupportType::FULL){
if(!isset($this->connections[$facing])){
$this->connections[$facing] = WallConnectionType::SHORT;
$changed++;
if ($above instanceof Wall){
if ($this->getSide($face) instanceof Wall) {
if ($above->getSide($face) instanceof Wall) $connectionType = WallConnectionType::TALL();

Check failure on line 135 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().

Check failure on line 135 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().

Check failure on line 135 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::TALL().
else if (!$this->post) {
$updated = true;
$connectionType = WallConnectionType::SHORT();

Check failure on line 138 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().

Check failure on line 138 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().

Check failure on line 138 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Use of legacy enum case accessor pocketmine\block\utils\WallConnectionType::SHORT().
$this->post = true;
}
}
}elseif(isset($this->connections[$facing])){
unset($this->connections[$facing]);
$changed++;
}

if ($this->getConnection($face) !== $connectionType) {
$updated = true;

$this->connections[$face] = $connectionType;

Check failure on line 147 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.1 / PHPStan analysis

Property pocketmine\block\Wall::$connections (array<2|3|4|5, pocketmine\block\utils\WallConnectionType>) does not accept non-empty-array<2|3|4|5, pocketmine\block\utils\WallConnectionType|null>.

Check failure on line 147 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.2 / PHPStan analysis

Property pocketmine\block\Wall::$connections (array<2|3|4|5, pocketmine\block\utils\WallConnectionType>) does not accept non-empty-array<2|3|4|5, pocketmine\block\utils\WallConnectionType|null>.

Check failure on line 147 in src/block/Wall.php

View workflow job for this annotation

GitHub Actions / PHP 8.3 / PHPStan analysis

Property pocketmine\block\Wall::$connections (array<2|3|4|5, pocketmine\block\utils\WallConnectionType>) does not accept non-empty-array<2|3|4|5, pocketmine\block\utils\WallConnectionType|null>.
}
}

$up = $this->getSide(Facing::UP)->getTypeId() !== BlockTypeIds::AIR;
if($up !== $this->post){
$this->post = $up;
$changed++;
return $updated;
}

public function recalculatePost(): bool
{
$updated = false;
$above = $this->getSide(Facing::UP);

$connections = count(array_filter(Facing::HORIZONTAL, function ($face) {
return $this->getConnection($face) !== WallConnectionType::NONE;
}));

// TODO: Lanterns and Hanging Signs
$post = false;
switch(get_class($above)) {
case Torch::class:
$post = $above->getFacing() === Facing::DOWN;
break;
case Trapdoor::class:
if ($above->isOpen()) {
$post = $this->getConnection($above->getFacing()) !== null;
}
break;
case Wall::class:
$post = $above->isPost();
break;
}

if (!$post) {
$post = $connections < 2;
if ($connections > 2){
if ($this->getConnection(Facing::NORTH) !== null && $this->getConnection(Facing::SOUTH) !== null) {
$post = $this->getConnection(Facing::EAST) !== null || $this->getConnection(Facing::WEST) !== null;
} else if ($this->getConnection(Facing::EAST) !== null && $this->getConnection(Facing::WEST) !== null) {
$post = $this->getConnection(Facing::NORTH) !== null || $this->getConnection(Facing::SOUTH) !== null;
} else $post = true;
}
}

if ($this->post !== $post) {
$updated = true;
$this->post = $post;
}

return $changed > 0;
return $updated;

}

protected function recalculateCollisionBoxes() : array{
Expand Down Expand Up @@ -154,4 +229,4 @@
public function getSupportType(int $facing) : SupportType{
return Facing::axis($facing) === Axis::Y ? SupportType::CENTER : SupportType::NONE;
}
}
}
2 changes: 2 additions & 0 deletions src/block/utils/WallConnectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
* TODO: These tags need to be removed once we get rid of LegacyEnumShimTrait (PM6)
* These are retained for backwards compatibility only.
*
* @method static WallConnectionType NONE()
* @method static WallConnectionType SHORT()
* @method static WallConnectionType TALL()
*/
enum WallConnectionType{
use LegacyEnumShimTrait;

case NONE;
case SHORT;
case TALL;
}
Loading