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 $connectionFace = Facing::from($connection & ~RailConnectionInfo::FLAG_ASCEND);
93 $other = $this->getSide($connectionFace);
94 $otherConnection = Facing::opposite($connectionFace)->value;
96 if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0){
97 $other = $other->getSide(Facing::UP);
99 }elseif(!($other instanceof
BaseRail)){
100 $other = $other->getSide(Facing::DOWN);
101 $otherConnection |= RailConnectionInfo::FLAG_ASCEND;
106 in_array($otherConnection, $other->getCurrentShapeConnections(),
true)
108 $connections[] = $connection;
121 private function getPossibleConnectionDirections(array $constraints) : array{
122 switch(count($constraints)){
126 Facing::NORTH->value =>
true,
127 Facing::SOUTH->value =>
true,
128 Facing::WEST->value =>
true,
129 Facing::EAST->value => true
131 foreach($possible as $p => $_){
132 $possible[$p | RailConnectionInfo::FLAG_ASCEND] =
true;
137 return $this->getPossibleConnectionDirectionsOneConstraint(array_shift($constraints));
141 throw new \InvalidArgumentException(
"Expected at most 2 constraints, got " . count($constraints));
152 $possible = [$opposite->value =>
true];
154 if(($constraint & RailConnectionInfo::FLAG_ASCEND) === 0){
156 $possible[$opposite->value | RailConnectionInfo::FLAG_ASCEND] =
true;
162 private function tryReconnect() : void{
163 $thisConnections = $this->getConnectedDirections();
166 $world = $this->position->getWorld();
168 $possible = $this->getPossibleConnectionDirections($thisConnections);
171 foreach($possible as $thisSide => $_){
172 $thisSideEnum = Facing::from($thisSide & ~RailConnectionInfo::FLAG_ASCEND);
173 $otherSide = Facing::opposite($thisSideEnum)->value;
175 $other = $this->getSide($thisSideEnum);
177 if(($thisSide & RailConnectionInfo::FLAG_ASCEND) !== 0){
178 $other = $other->getSide(Facing::UP);
180 }elseif(!($other instanceof BaseRail)){
181 $other = $other->getSide(Facing::DOWN);
182 $otherSide |= RailConnectionInfo::FLAG_ASCEND;
185 if(!($other instanceof BaseRail) || count($otherConnections = $other->getConnectedDirections()) >= 2){
190 $otherPossible = $other->getPossibleConnectionDirections($otherConnections);
192 if(isset($otherPossible[$otherSide])){
193 $otherConnections[] = $otherSide;
194 $other->setConnections($otherConnections);
195 $world->setBlock($other->position, $other);
198 $thisConnections[] = $thisSide;
199 $continue = count($thisConnections) < 2;
207 $this->setConnections($thisConnections);
208 $world->setBlock($this->position, $this);
215 private function setConnections(array $connections) : void{
216 if(count($connections) === 1){
217 $connections[] = Facing::opposite(Facing::from($connections[0] & ~RailConnectionInfo::FLAG_ASCEND))->value;
218 }elseif(count($connections) !== 2){
219 throw new \InvalidArgumentException(
"Expected exactly 2 connections, got " . count($connections));
222 $this->setShapeFromConnections($connections);
226 $world = $this->position->getWorld();
227 if(!$this->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){
228 $world->useBreakOn($this->position);
230 foreach($this->getCurrentShapeConnections() as $connection){
231 if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0 && !$this->getSide(Facing::from($connection & ~RailConnectionInfo::FLAG_ASCEND))->getSupportType(Facing::UP)->hasEdgeSupport()){
232 $world->useBreakOn($this->position);