smatz@8587: /* $Id$ */ smatz@8587: rubidium@10429: /** @file road.cpp Generic road related functions. */ rubidium@10429: rubidium@8137: #include "stdafx.h" rubidium@8137: #include "openttd.h" rubidium@8137: #include "rail_map.h" rubidium@8137: #include "road_map.h" rubidium@8598: #include "road_internal.h" rubidium@8137: #include "water_map.h" rubidium@8732: #include "genworld.h" rubidium@8750: #include "player_func.h" rubidium@8750: #include "player_base.h" rubidium@9282: #include "engine_func.h" peter1138@10382: #include "engine_base.h" rubidium@8732: #include "settings_type.h" rubidium@8732: #include "date_func.h" rubidium@8137: rubidium@8137: bool IsPossibleCrossing(const TileIndex tile, Axis ax) rubidium@8137: { rubidium@8137: return (IsTileType(tile, MP_RAILWAY) && rubidium@8137: !HasSignals(tile) && rubidium@8137: GetTrackBits(tile) == (ax == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) && rubidium@8137: GetTileSlope(tile, NULL) == SLOPE_FLAT); rubidium@8137: } rubidium@8137: rubidium@8137: RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) rubidium@8137: { rubidium@8137: for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { rubidium@8137: const TileIndex neighbor_tile = TileAddByDiagDir(tile, dir); rubidium@8137: rubidium@8137: /* Get the Roadbit pointing to the neighbor_tile */ rubidium@8137: const RoadBits target_rb = DiagDirToRoadBits(dir); rubidium@8137: rubidium@8137: /* If the roadbit is in the current plan */ rubidium@8137: if (org_rb & target_rb) { rubidium@8137: bool connective = false; rubidium@8137: const RoadBits mirrored_rb = MirrorRoadBits(target_rb); rubidium@8137: rubidium@8137: switch (GetTileType(neighbor_tile)) { rubidium@8137: /* Allways connective ones */ rubidium@8137: case MP_CLEAR: case MP_TREES: rubidium@8137: connective = true; rubidium@8137: break; rubidium@8137: rubidium@8137: /* The conditionaly connective ones */ rubidium@8137: case MP_TUNNELBRIDGE: rubidium@8137: case MP_STATION: rubidium@8137: case MP_ROAD: { rubidium@8137: const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); rubidium@8137: rubidium@8137: /* Accept only connective tiles */ rubidium@8137: connective = (neighbor_rb & mirrored_rb) || // Neighbor has got the fitting RoadBit truelight@8328: CountBits(neighbor_rb) == 1; // Neighbor has got only one Roadbit rubidium@8137: rubidium@8137: } break; rubidium@8137: rubidium@8137: case MP_RAILWAY: rubidium@8137: connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir)); rubidium@8137: break; rubidium@8137: rubidium@8137: case MP_WATER: rubidium@8137: /* Check for real water tile */ rubidium@8137: connective = !IsWater(neighbor_tile); rubidium@8137: break; rubidium@8137: rubidium@8137: /* The defentetly not connective ones */ rubidium@8137: default: break; rubidium@8137: } rubidium@8137: rubidium@8137: /* If the neighbor tile is inconnective remove the planed road connection to it */ rubidium@8137: if (!connective) org_rb ^= target_rb; rubidium@8137: rubidium@8137: } rubidium@8137: } rubidium@8137: rubidium@8137: return org_rb; rubidium@8137: } rubidium@8732: rubidium@8732: bool HasRoadTypesAvail(const PlayerID p, const RoadTypes rts) rubidium@8732: { rubidium@8732: RoadTypes avail_roadtypes; rubidium@8732: rubidium@8732: if (p == OWNER_TOWN || _game_mode == GM_EDITOR || IsGeneratingWorld()) { rubidium@8732: avail_roadtypes = ROADTYPES_ROAD; rubidium@8732: } else { rubidium@11161: if (!IsValidPlayerID(p)) return false; rubidium@8732: avail_roadtypes = (RoadTypes)GetPlayer(p)->avail_roadtypes | ROADTYPES_ROAD; // road is available for always for everybody rubidium@8732: } rubidium@8732: return (rts & ~avail_roadtypes) == 0; rubidium@8732: } rubidium@8732: rubidium@8732: bool ValParamRoadType(const RoadType rt) rubidium@8732: { rubidium@8732: return HasRoadTypesAvail(_current_player, RoadTypeToRoadTypes(rt)); rubidium@8732: } rubidium@8732: rubidium@8732: RoadTypes GetPlayerRoadtypes(PlayerID p) rubidium@8732: { rubidium@8732: RoadTypes rt = ROADTYPES_NONE; rubidium@8732: peter1138@10382: Engine *e; peter1138@10382: FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { peter1138@10382: const EngineInfo *ei = &e->info; rubidium@8732: rubidium@10775: if (HasBit(ei->climates, _settings_game.game_creation.landscape) && rubidium@8732: (HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) { rubidium@8732: SetBit(rt, HasBit(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD); rubidium@8732: } rubidium@8732: } rubidium@8732: rubidium@8732: return rt; rubidium@8732: }