00001
00002
00049 #include "stdafx.h"
00050 #include "openttd.h"
00051 #include "station_map.h"
00052 #include "viewport_func.h"
00053 #include "settings_type.h"
00054 #include "landscape.h"
00055 #include "rail_type.h"
00056 #include "debug.h"
00057 #include "tunnel_map.h"
00058 #include "road_map.h"
00059 #include "bridge_map.h"
00060 #include "bridge.h"
00061 #include "rail_map.h"
00062 #include "train.h"
00063 #include "rail_gui.h"
00064 #include "transparency.h"
00065 #include "tunnelbridge_map.h"
00066 #include "vehicle_func.h"
00067 #include "company_base.h"
00068 #include "tunnelbridge.h"
00069 #include "engine_func.h"
00070 #include "elrail_func.h"
00071 #include "engine_base.h"
00072
00073 #include "table/sprites.h"
00074 #include "table/elrail_data.h"
00075
00076 static inline TLG GetTLG(TileIndex t)
00077 {
00078 return (TLG)((HasBit(TileX(t), 0) << 1) + HasBit(TileY(t), 0));
00079 }
00080
00087 static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
00088 {
00089 switch (GetTileType(t)) {
00090 case MP_RAILWAY:
00091 if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
00092 switch (GetRailTileType(t)) {
00093 case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
00094 return GetTrackBits(t);
00095 case RAIL_TILE_WAYPOINT:
00096 return GetRailWaypointBits(t);
00097 default:
00098 return TRACK_BIT_NONE;
00099 }
00100 break;
00101
00102 case MP_TUNNELBRIDGE:
00103 if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
00104 if (override != NULL && (IsTunnel(t) || GetTunnelBridgeLength(t, GetOtherBridgeEnd(t)) > 0)) {
00105 *override = 1 << GetTunnelBridgeDirection(t);
00106 }
00107 return DiagDirToDiagTrackBits(GetTunnelBridgeDirection(t));
00108
00109 case MP_ROAD:
00110 if (!IsLevelCrossing(t)) return TRACK_BIT_NONE;
00111 if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
00112 return GetCrossingRailBits(t);
00113
00114 case MP_STATION:
00115 if (!IsRailwayStation(t)) return TRACK_BIT_NONE;
00116 if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
00117 if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
00118 return TrackToTrackBits(GetRailStationTrack(t));
00119
00120 default:
00121 return TRACK_BIT_NONE;
00122 }
00123 }
00124
00129 static void AdjustTileh(TileIndex tile, Slope *tileh)
00130 {
00131 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
00132 if (IsTunnel(tile)) {
00133 *tileh = SLOPE_STEEP;
00134 } else if (*tileh != SLOPE_FLAT) {
00135 *tileh = SLOPE_FLAT;
00136 } else {
00137 *tileh = InclinedSlope(GetTunnelBridgeDirection(tile));
00138 }
00139 }
00140 }
00141
00149 static byte GetPCPElevation(TileIndex tile, DiagDirection PCPpos)
00150 {
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 byte z = GetSlopeZ(TileX(tile) * TILE_SIZE + min(x_pcp_offsets[PCPpos], TILE_SIZE - 1), TileY(tile) * TILE_SIZE + min(y_pcp_offsets[PCPpos], TILE_SIZE - 1));
00166 return (z + 2) & ~3;
00167 }
00168
00176 void DrawCatenaryOnTunnel(const TileInfo *ti)
00177 {
00178
00179 static const int _tunnel_wire_BB[4][4] = {
00180 { 0, 1, 16, 15 },
00181 { 1, 0, 15, 16 },
00182 { 0, 1, 16, 15 },
00183 { 1, 0, 15, 16 },
00184 };
00185
00186 DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
00187
00188 const SortableSpriteStruct *sss = &CatenarySpriteData_Tunnel[dir];
00189 const int *BB_data = _tunnel_wire_BB[dir];
00190 AddSortableSpriteToDraw(
00191 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
00192 BB_data[2] - sss->x_offset, BB_data[3] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset + 1,
00193 GetTileZ(ti->tile) + sss->z_offset,
00194 IsTransparencySet(TO_CATENARY),
00195 BB_data[0] - sss->x_offset, BB_data[1] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset
00196 );
00197 }
00198
00202 static void DrawCatenaryRailway(const TileInfo *ti)
00203 {
00204
00205
00206
00207 TrackBits trackconfig[TS_END];
00208 bool isflat[TS_END];
00209
00210 Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
00211
00212
00213
00214 if (IsHalftileSlope(tileh[TS_HOME])) tileh[TS_HOME] = SLOPE_FLAT;
00215
00216 TLG tlg = GetTLG(ti->tile);
00217 byte PCPstatus = 0;
00218 byte OverridePCP = 0;
00219 byte PPPpreferred[DIAGDIR_END];
00220 byte PPPallowed[DIAGDIR_END];
00221
00222
00223
00224
00225
00226
00227
00228 trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
00229
00230 isflat[TS_HOME] = ((trackconfig[TS_HOME] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
00231
00232 AdjustTileh(ti->tile, &tileh[TS_HOME]);
00233
00234 for (DiagDirection i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
00235 TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
00236 Foundation foundation = FOUNDATION_NONE;
00237 byte elevation = GetPCPElevation(ti->tile, i);
00238
00239
00240
00241 tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
00242 trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
00243 if (IsTunnelTile(neighbour) && i != GetTunnelBridgeDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
00244
00245
00246
00247 if (elevation != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
00248
00249 isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
00250
00251 PPPpreferred[i] = 0xFF;
00252 PPPallowed[i] = AllowedPPPonPCP[i];
00253
00254
00255
00256 for (uint k = 0; k < NUM_TRACKS_AT_PCP; k++) {
00257
00258 if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
00259 IsBridgeTile(neighbour) &&
00260 GetTunnelBridgeDirection(neighbour) == ReverseDiagDir(i)) {
00261 continue;
00262 }
00263
00264
00265
00266 if (HasBit(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) {
00267
00268
00269 DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i);
00270 SetBit(PCPstatus, i);
00271
00272 PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
00273 PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
00274 }
00275 }
00276
00277
00278 if (!HasBit(PCPstatus, i)) {
00279 PPPpreferred[i] = 0;
00280 PPPallowed[i] = 0;
00281 }
00282
00283
00284 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
00285
00286
00287 if (trackconfig[TS_NEIGHBOUR] != TRACK_BIT_NONE && IsTileType(neighbour, MP_RAILWAY) && HasCatenary(GetRailType(neighbour))) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]);
00288 if (IsBridgeTile(neighbour)) {
00289 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetTunnelBridgeDirection(neighbour)));
00290 }
00291
00292 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
00293
00294
00295
00296 if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
00297
00298 AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
00299
00300
00301
00302
00303 if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
00304 for (uint k = 0; k < NUM_IGNORE_GROUPS; k++) {
00305 if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) ClrBit(PCPstatus, i);
00306 }
00307 }
00308
00309
00310
00311
00312
00313 if ((PPPallowed[i] & PPPpreferred[i]) != 0) PPPallowed[i] &= PPPpreferred[i];
00314
00315 if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
00316 Track bridgetrack = GetBridgeAxis(ti->tile) == AXIS_X ? TRACK_X : TRACK_Y;
00317 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
00318
00319 if ((height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) &&
00320 (i == PCPpositions[bridgetrack][0] || i == PCPpositions[bridgetrack][1])) {
00321 SetBit(OverridePCP, i);
00322 }
00323 }
00324
00325 if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i)) {
00326 for (Direction k = DIR_BEGIN; k < DIR_END; k++) {
00327 byte temp = PPPorder[i][GetTLG(ti->tile)][k];
00328
00329 if (HasBit(PPPallowed[i], temp)) {
00330 uint x = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
00331 uint y = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
00332
00333
00334 if (!HasBit(OwnedPPPonPCP[i], temp)) {
00335
00336 if (trackconfig[TS_NEIGHBOUR] != 0) break;
00337 continue;
00338 }
00339
00340 AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE,
00341 elevation, IsTransparencySet(TO_CATENARY), -1, -1);
00342
00343 break;
00344 }
00345 }
00346 }
00347 }
00348
00349
00350 if (IsTunnelTile(ti->tile)) return;
00351
00352
00353 if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_CATENARY)) {
00354 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
00355
00356 if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
00357 }
00358
00359
00360 for (Track t = TRACK_BEGIN; t < TRACK_END; t++) {
00361 if (HasBit(trackconfig[TS_HOME], t)) {
00362 byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
00363 (HasBit(PCPstatus, PCPpositions[t][1]) << 1);
00364
00365 const SortableSpriteStruct *sss;
00366 int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3;
00367
00368 assert(PCPconfig != 0);
00369 assert(!IsSteepSlope(tileh[TS_HOME]));
00370 sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]];
00371
00372
00373
00374
00375
00376
00377 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
00378 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset,
00379 IsTransparencySet(TO_CATENARY));
00380 }
00381 }
00382 }
00383
00384 void DrawCatenaryOnBridge(const TileInfo *ti)
00385 {
00386 TileIndex end = GetSouthernBridgeEnd(ti->tile);
00387 TileIndex start = GetOtherBridgeEnd(end);
00388
00389 uint length = GetTunnelBridgeLength(start, end);
00390 uint num = GetTunnelBridgeLength(ti->tile, start) + 1;
00391 uint height;
00392
00393 const SortableSpriteStruct *sss;
00394 Axis axis = GetBridgeAxis(ti->tile);
00395 TLG tlg = GetTLG(ti->tile);
00396
00397 CatenarySprite offset = (CatenarySprite)(axis == AXIS_X ? 0 : WIRE_Y_FLAT_BOTH - WIRE_X_FLAT_BOTH);
00398
00399 if ((length % 2) && num == length) {
00400
00401
00402 sss = &CatenarySpriteData[WIRE_X_FLAT_BOTH + offset];
00403 } else {
00404
00405 sss = &CatenarySpriteData[WIRE_X_FLAT_SW + (num % 2) + offset];
00406 }
00407
00408 height = GetBridgeHeight(end);
00409
00410 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
00411 sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset,
00412 IsTransparencySet(TO_CATENARY)
00413 );
00414
00415
00416
00417 if (num % 2) {
00418 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_NE : DIAGDIR_NW);
00419 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE);
00420 if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos);
00421 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos];
00422 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos];
00423 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_CATENARY), -1, -1);
00424 }
00425
00426
00427 if (GetTunnelBridgeLength(ti->tile, start) + 1 == length) {
00428 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_SW : DIAGDIR_SE);
00429 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE);
00430 if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos);
00431 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos];
00432 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos];
00433 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_CATENARY), -1, -1);
00434 }
00435 }
00436
00437 void DrawCatenary(const TileInfo *ti)
00438 {
00439 switch (GetTileType(ti->tile)) {
00440 case MP_RAILWAY:
00441 if (IsRailDepot(ti->tile)) {
00442 const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)];
00443
00444
00445 AddSortableSpriteToDraw(
00446 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
00447 sss->x_size, sss->y_size, sss->z_size,
00448 GetTileMaxZ(ti->tile) + sss->z_offset,
00449 IsTransparencySet(TO_CATENARY)
00450 );
00451 return;
00452 }
00453 break;
00454
00455 case MP_TUNNELBRIDGE:
00456 case MP_ROAD:
00457 case MP_STATION:
00458 break;
00459
00460 default: return;
00461 }
00462 DrawCatenaryRailway(ti);
00463 }
00464
00465 int32 SettingsDisableElrail(int32 p1)
00466 {
00467 Vehicle *v;
00468 Company *c;
00469 bool disable = (p1 != 0);
00470
00471
00472 const RailType old_railtype = disable ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL;
00473 const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC;
00474
00475
00476 Engine *e;
00477 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
00478 RailVehicleInfo *rv_info = &e->u.rail;
00479
00480 if (rv_info->engclass == 2 && rv_info->railtype == old_railtype) {
00481
00482 rv_info->railtype = new_railtype;
00483 }
00484 }
00485
00486
00487
00488 if (disable) {
00489 FOR_ALL_VEHICLES(v) {
00490 if (v->type == VEH_TRAIN && v->u.rail.railtype == RAILTYPE_ELECTRIC) {
00491
00492
00493 v->u.rail.compatible_railtypes |= RAILTYPES_RAIL;
00494 v->u.rail.railtype = RAILTYPE_RAIL;
00495 SetBit(v->u.rail.flags, VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL);
00496 }
00497 }
00498 }
00499
00500
00501 FOR_ALL_VEHICLES(v) {
00502
00503 if (v->type == VEH_TRAIN && IsFrontEngine(v)) {
00504 TrainPowerChanged(v);
00505 UpdateTrainAcceleration(v);
00506 }
00507 }
00508
00509 FOR_ALL_COMPANIES(c) c->avail_railtypes = GetCompanyRailtypes(c->index);
00510
00511
00512
00513
00514 ReinitGuiAfterToggleElrail(disable);
00515 return 0;
00516 }