-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
base: stable
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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; | ||
|
@@ -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) || | ||
($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
|
||
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
|
||
$boxes = $above->recalculateCollisionBoxes(); | ||
|
||
foreach($boxes as $bb) { | ||
if ($bb->minY == 0) { | ||
Check failure on line 115 in src/block/Wall.php
|
||
$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
|
||
default => false | ||
}; | ||
if ($tall) { | ||
$connectionType = WallConnectionType::TALL(); | ||
Check failure on line 127 in src/block/Wall.php
|
||
} | ||
} | ||
} | ||
} | ||
|
||
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
|
||
else if (!$this->post) { | ||
$updated = true; | ||
$connectionType = WallConnectionType::SHORT(); | ||
Check failure on line 138 in src/block/Wall.php
|
||
$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
|
||
} | ||
} | ||
|
||
$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; | ||
} | ||
0x00032 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return $changed > 0; | ||
return $updated; | ||
|
||
} | ||
|
||
protected function recalculateCollisionBoxes() : array{ | ||
|
@@ -154,4 +229,4 @@ | |
public function getSupportType(int $facing) : SupportType{ | ||
return Facing::axis($facing) === Axis::Y ? SupportType::CENTER : SupportType::NONE; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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)