/** * Clean up unnecessary RoadBits of a planed tile. * @param tile current tile * @param org_rb planed RoadBits * @return optimised RoadBits */ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) { if (!IsValidTile(tile)) return ROAD_NONE; for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { const TileIndex neighbor_tile = TileAddByDiagDir(tile, dir); /* Get the Roadbit pointing to the neighbor_tile */ const RoadBits target_rb = DiagDirToRoadBits(dir); /* If the roadbit is in the current plan */ if (org_rb & target_rb) { bool connective = false; const RoadBits mirrored_rb = MirrorRoadBits(target_rb); if (IsValidTile(neighbor_tile)) { switch (GetTileType(neighbor_tile)) { /* Always connective ones */ case MP_CLEAR: case MP_TREES: connective = true; break; /* The conditionally connective ones */ case MP_TUNNELBRIDGE: case MP_STATION: case MP_ROAD: if (IsNormalRoadTile(neighbor_tile)) { /* Always connective */ connective = true; } else { const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); /* Accept only connective tiles */ connective = (neighbor_rb & mirrored_rb) != ROAD_NONE; } break; case MP_RAILWAY: connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir)); break; case MP_WATER: /* Check for real water tile */ connective = !IsWater(neighbor_tile); break; /* The definitely not connective ones */ default: break; } } /* If the neighbor tile is inconnective, remove the planed road connection to it */ if (!connective) org_rb ^= target_rb; } } return org_rb; }
/** * If required, connects a new structure to an existing road or tram by building the missing roadbit. * @param tile Tile containing the structure to connect. * @param direction Direction to check. */ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) { tile += TileOffsByDiagDir(direction); /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { if (GetRoadBits(tile, _cur_roadtype) != ROAD_NONE) { DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, CMD_BUILD_ROAD); } } }
/** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */ static DiagDirection GetSingleTramBit(TileIndex tile) { if (IsNormalRoadTile(tile)) { RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM); switch (rb) { case ROAD_NW: return DIAGDIR_NW; case ROAD_SW: return DIAGDIR_SW; case ROAD_SE: return DIAGDIR_SE; case ROAD_NE: return DIAGDIR_NE; default: break; } } return INVALID_DIAGDIR; }
/** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */ FORCEINLINE DiagDirection GetSingleTramBit(TileIndex tile) { assert(IsTram()); // this function shouldn't be called in other cases if (IsNormalRoadTile(tile)) { RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM); switch (rb) { case ROAD_NW: return DIAGDIR_NW; case ROAD_SW: return DIAGDIR_SW; case ROAD_SE: return DIAGDIR_SE; case ROAD_NE: return DIAGDIR_NE; default: break; } } return INVALID_DIAGDIR; }
/* static */ bool ScriptRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2) { if (!::IsValidTile(t1)) return false; if (!::IsValidTile(t2)) return false; if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; /* Tiles not neighbouring */ if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false; RoadBits r1 = ::GetAnyRoadBits(t1, ScriptObject::GetRoadType()); RoadBits r2 = ::GetAnyRoadBits(t2, ScriptObject::GetRoadType()); uint dir_1 = (::TileX(t1) == ::TileX(t2)) ? (::TileY(t1) < ::TileY(t2) ? 2 : 0) : (::TileX(t1) < ::TileX(t2) ? 1 : 3); uint dir_2 = 2 ^ dir_1; DisallowedRoadDirections drd2 = IsNormalRoadTile(t2) ? GetDisallowedRoadDirections(t2) : DRD_NONE; return HasBit(r1, dir_1) && HasBit(r2, dir_2) && drd2 != DRD_BOTH && drd2 != (dir_1 > dir_2 ? DRD_SOUTHBOUND : DRD_NORTHBOUND); }