41        if($blockReplace->getAdjacentSupportType(
Facing::DOWN)->hasEdgeSupport()){
 
   42            return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
 
 
   49        $this->tryReconnect();
 
 
   57    protected static function searchState(array $connections, array $lookup) : ?int{
 
   58        $shape = array_search($connections, $lookup, true);
 
   60            $shape = array_search(array_reverse($connections), $lookup, 
true);
 
   62        return $shape === 
false ? null : $shape;
 
 
   86    private function getConnectedDirections() : array{
 
   91        foreach($this->getCurrentShapeConnections() as $connection){
 
   92            $other = $this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND);
 
   93            $otherConnection = Facing::opposite($connection & ~RailConnectionInfo::FLAG_ASCEND);
 
   95            if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0){
 
   96                $other = $other->getSide(Facing::UP);
 
   98            }elseif(!($other instanceof 
BaseRail)){ 
 
   99                $other = $other->getSide(Facing::DOWN);
 
  100                $otherConnection |= RailConnectionInfo::FLAG_ASCEND;
 
  105                in_array($otherConnection, $other->getCurrentShapeConnections(), 
true)
 
  107                $connections[] = $connection;
 
  120    private function getPossibleConnectionDirections(array $constraints) : array{
 
  121        switch(count($constraints)){
 
  125                    Facing::NORTH => 
true,
 
  126                    Facing::SOUTH => 
true,
 
  127                    Facing::WEST => 
true,
 
  130                foreach($possible as $p => $_){
 
  131                    $possible[$p | RailConnectionInfo::FLAG_ASCEND] = 
true;
 
  136                return $this->getPossibleConnectionDirectionsOneConstraint(array_shift($constraints));
 
  140                throw new \InvalidArgumentException(
"Expected at most 2 constraints, got " . count($constraints));
 
  151        $possible = [$opposite => 
true];
 
  153        if(($constraint & RailConnectionInfo::FLAG_ASCEND) === 0){
 
  155            $possible[$opposite | RailConnectionInfo::FLAG_ASCEND] = 
true;
 
 
  161    private function tryReconnect() : void{
 
  162        $thisConnections = $this->getConnectedDirections();
 
  165        $world = $this->position->getWorld();
 
  167            $possible = $this->getPossibleConnectionDirections($thisConnections);
 
  170            foreach($possible as $thisSide => $_){
 
  171                $otherSide = Facing::opposite($thisSide & ~RailConnectionInfo::FLAG_ASCEND);
 
  173                $other = $this->getSide($thisSide & ~RailConnectionInfo::FLAG_ASCEND);
 
  175                if(($thisSide & RailConnectionInfo::FLAG_ASCEND) !== 0){
 
  176                    $other = $other->getSide(Facing::UP);
 
  178                }elseif(!($other instanceof BaseRail)){ 
 
  179                    $other = $other->getSide(Facing::DOWN);
 
  180                    $otherSide |= RailConnectionInfo::FLAG_ASCEND;
 
  183                if(!($other instanceof BaseRail) || count($otherConnections = $other->getConnectedDirections()) >= 2){
 
  188                $otherPossible = $other->getPossibleConnectionDirections($otherConnections);
 
  190                if(isset($otherPossible[$otherSide])){
 
  191                    $otherConnections[] = $otherSide;
 
  192                    $other->setConnections($otherConnections);
 
  193                    $world->setBlock($other->position, $other);
 
  196                    $thisConnections[] = $thisSide;
 
  197                    $continue = count($thisConnections) < 2;
 
  205            $this->setConnections($thisConnections);
 
  206            $world->setBlock($this->position, $this);
 
  213    private function setConnections(array $connections) : void{
 
  214        if(count($connections) === 1){
 
  215            $connections[] = Facing::opposite($connections[0] & ~RailConnectionInfo::FLAG_ASCEND);
 
  216        }elseif(count($connections) !== 2){
 
  217            throw new \InvalidArgumentException(
"Expected exactly 2 connections, got " . count($connections));
 
  220        $this->setShapeFromConnections($connections);
 
  224        $world = $this->position->getWorld();
 
  225        if(!$this->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){
 
  226            $world->useBreakOn($this->position);
 
  228            foreach($this->getCurrentShapeConnections() as $connection){
 
  229                if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0 && !$this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND)->getSupportType(Facing::UP)->hasEdgeSupport()){
 
  230                    $world->useBreakOn($this->position);