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);