# HG changeset patch # User celestar # Date 1167390219 0 # Node ID 3e0dd1f014ca4f8005de57fe6a8c11518641ec37 # Parent fd60d4ecc921fb19503158e1fb2504c84211f18d (svn r7610) [cbh] - Codechange: Created seperate Tile Type Procs for tunnel and bridge tiles diff -r fd60d4ecc921 -r 3e0dd1f014ca landscape.c --- a/landscape.c Fri Dec 29 10:13:35 2006 +0000 +++ b/landscape.c Fri Dec 29 11:03:39 2006 +0000 @@ -32,10 +32,10 @@ _tile_type_water_procs, _tile_type_dummy_procs, _tile_type_industry_procs, - _tile_type_tunnelbridge_procs, + _tile_type_tunnel_procs, _tile_type_unmovable_procs, - _tile_type_tunnelbridge_procs, - _tile_type_tunnelbridge_procs; + _tile_type_bridge_procs, + _tile_type_bridge_procs; const TileTypeProcs * const _tile_type_procs[16] = { &_tile_type_clear_procs, @@ -47,10 +47,10 @@ &_tile_type_water_procs, &_tile_type_dummy_procs, &_tile_type_industry_procs, - &_tile_type_tunnelbridge_procs, + &_tile_type_tunnel_procs, &_tile_type_unmovable_procs, - &_tile_type_tunnelbridge_procs, - &_tile_type_tunnelbridge_procs, + &_tile_type_bridge_procs, + &_tile_type_bridge_procs, NULL, NULL, NULL diff -r fd60d4ecc921 -r 3e0dd1f014ca tunnelbridge_cmd.c --- a/tunnelbridge_cmd.c Fri Dec 29 10:13:35 2006 +0000 +++ b/tunnelbridge_cmd.c Fri Dec 29 11:03:39 2006 +0000 @@ -641,17 +641,18 @@ return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge; } -static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags) +static int32 ClearTile_Tunnel(TileIndex tile, byte flags) { - if (IsTunnelTile(tile)) { - if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST); - return DoClearTunnel(tile, flags); - } else if (IsBridgeTile(tile)) { // XXX Is this necessary? - if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); - return DoClearBridge(tile, flags); - } + assert(IsTunnelTile(tile)); + if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST); + return DoClearTunnel(tile, flags); +} - return CMD_ERROR; +static int32 ClearTile_Bridge(TileIndex tile, byte flags) +{ + assert(IsBridgeTile(tile)); + if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); + return DoClearBridge(tile, flags); } int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec) @@ -787,9 +788,32 @@ } /** - * Draws a tunnel of bridge tile. - * For tunnels, this is rather simple, as you only needa draw the entrance. - * Bridges are a bit more complex. base_offset is where the sprite selection comes into play + * Draws a tunnel tile. + * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 + */ +static void DrawTile_Tunnel(TileInfo *ti) +{ + uint32 image; + + if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) { + image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; + } else { + image = SPR_TUNNEL_ENTRY_REAR_ROAD; + } + + if (HasTunnelSnowOrDesert(ti->tile)) image += 32; + + image += GetTunnelDirection(ti->tile) * 2; + DrawGroundSprite(image); + if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + + AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); + DrawBridgeMiddle(ti); +} + +/** + * Draws a bridge tile. + * base_offset is where the sprite selection comes into play * and it works a bit like a bitmask.

For bridge heads: *

* Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 */ -static void DrawTile_TunnelBridge(TileInfo *ti) +static void DrawTile_Bridge(TileInfo *ti) { uint32 image; - if (IsTunnelTile(ti->tile)) { - if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) { - image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; - } else { - image = SPR_TUNNEL_ENTRY_REAR_ROAD; - } - - if (HasTunnelSnowOrDesert(ti->tile)) image += 32; - - image += GetTunnelDirection(ti->tile) * 2; - DrawGroundSprite(image); - if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); - - AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); - DrawBridgeMiddle(ti); - } else if (IsBridgeTile(ti->tile)) { // XXX is this necessary? - int base_offset; - bool ice = HasBridgeSnowOrDesert(ti->tile); - - if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { - base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; - assert(base_offset != 8); /* This one is used for roads */ - } else { - base_offset = 8; - } - - /* as the lower 3 bits are used for other stuff, make sure they are clear */ - assert( (base_offset & 0x07) == 0x00); + int base_offset; + bool ice = HasBridgeSnowOrDesert(ti->tile); - if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) { - int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))); - if (f != 0) DrawFoundation(ti, f); - } - - // HACK Wizardry to convert the bridge ramp direction into a sprite offset - base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4; - - if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head - - /* Table number 6 always refers to the bridge heads for any bridge type */ - image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; + if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { + base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; + assert(base_offset != 8); /* This one is used for roads */ + } else { + base_offset = 8; + } - if (!ice) { - DrawClearLandTile(ti, 3); - } else { - DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]); - } - - if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + /* as the lower 3 bits are used for other stuff, make sure they are clear */ + assert( (base_offset & 0x07) == 0x00); - // draw ramp - if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); - /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on - * it doesn't disappear behind it - */ - AddSortableSpriteToDraw( - image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z - ); + if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) { + int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))); + if (f != 0) DrawFoundation(ti, f); + } - DrawBridgeMiddle(ti); + // HACK Wizardry to convert the bridge ramp direction into a sprite offset + base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4; + + if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head + + /* Table number 6 always refers to the bridge heads for any bridge type */ + image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; + + if (!ice) { + DrawClearLandTile(ti, 3); + } else { + DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]); } + + if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); + + // draw ramp + if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); + /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on + * it doesn't disappear behind it + */ + AddSortableSpriteToDraw( + image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z + ); + + DrawBridgeMiddle(ti); } @@ -987,76 +994,111 @@ } - -static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y) +/** Gets the absolute z coordinate of a point inside a tunnel tile + * When we're on the track (that means between position 5 and 10) + * on the coordinate perpendicular to the track it returns only the + * base height of the tile (because the track is horizontal). + * Outside this range (from 0 to 4 and from 11 to 15) it returns the + * "true" Z coordinate of the tile by taking the slope into account + * @param tile The index of the tile we are talking about + * @param x Absolute or relative x coordinate + * @param y Absolute or relative y coordinate + * @return Absolute z coordinate + */ +static uint GetSlopeZ_Tunnel(TileIndex tile, uint x, uint y) { - uint z; + uint z, pos; Slope tileh = GetTileSlope(tile, &z); x &= 0xF; y &= 0xF; - if (IsTunnelTile(tile)) { - uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); - - // In the tunnel entrance? - if (5 <= pos && pos <= 10) return z; - } else { - DiagDirection dir = GetBridgeRampDirection(tile); - uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); - - // On the bridge ramp? - if (5 <= pos && pos <= 10) { - uint delta; - - if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; - if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; + pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); - if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT; - switch (dir) { - default: NOT_REACHED(); - case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break; - case DIAGDIR_SE: delta = y / 2; break; - case DIAGDIR_SW: delta = x / 2; break; - case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break; - } - return z + 1 + delta; - } else { - uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir)); - - if (f != 0) { - if (IsSteepSlope(tileh)) { - z += TILE_HEIGHT; - } else if (f < 15) { - return z + TILE_HEIGHT; - } - tileh = _inclined_tileh[f - 15]; - } - } - } + // In the tunnel entrance? + if (5 <= pos && pos <= 10) return z; return z + GetPartialZ(x, y, tileh); } -static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh) +/** Gets the absolute z coordinate of a point inside a bridge tile + * When we're on the track (that means between position 5 and 10) + * on the coordinate perpendicular to the track it returns the base + * height of the ramp + * Outside this range (from 0 to 4 and from 11 to 15) it returns the + * "true" Z coordinate of the tile by taking the slope into account + * @param tile The index of the tile we are talking about + * @param x Absolute or relative x coordinate + * @param y Absolute or relative y coordinate + * @return Absolute z coordinate + */ +static uint GetSlopeZ_Bridge(TileIndex tile, uint x, uint y) { - if (IsTunnelTile(tile)) { + uint z, pos; + Slope tileh = GetTileSlope(tile, &z); + DiagDirection dir = GetBridgeRampDirection(tile); + + x &= 0xF; + y &= 0xF; + + pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); + + // On the bridge ramp? + if (5 <= pos && pos <= 10) { + uint delta; + + if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; + + if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; + + if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT; + switch (dir) { + default: NOT_REACHED(); + case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break; + case DIAGDIR_SE: delta = y / 2; break; + case DIAGDIR_SW: delta = x / 2; break; + case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break; + } + return z + 1 + delta; + } else { + uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir)); + + if (f != 0) { + if (IsSteepSlope(tileh)) { + z += TILE_HEIGHT; + } else if (f < 15) { + return z + TILE_HEIGHT; + } + tileh = _inclined_tileh[f - 15]; + } + } + return z + GetPartialZ(x, y, tileh); +} + +static Slope GetSlopeTileh_Tunnel(TileIndex tile, Slope tileh) +{ + return tileh; +} + +static Slope GetSlopeTileh_Bridge(TileIndex tile, Slope tileh) +{ + if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) { return tileh; } else { - if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) { - return tileh; - } else { - uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile))); + uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile))); - if (f == 0) return tileh; - if (f < 15) return SLOPE_FLAT; - return _inclined_tileh[f - 15]; - } + if (f == 0) return tileh; + if (f < 15) return SLOPE_FLAT; + return _inclined_tileh[f - 15]; } } +static void GetAcceptedCargo_Tunnel(TileIndex tile, AcceptedCargo ac) +{ + /* not used */ +} -static void GetAcceptedCargo_TunnelBridge(TileIndex tile, AcceptedCargo ac) +static void GetAcceptedCargo_Bridge(TileIndex tile, AcceptedCargo ac) { /* not used */ } @@ -1093,69 +1135,104 @@ 0, 0, 0, }; -static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) +static void GetTileDesc_Tunnel(TileIndex tile, TileDesc *td) { - if (IsTunnelTile(tile)) { - td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ? - STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; - } else { - td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; - } + td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ? STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; + td->owner = GetTileOwner(tile); +} + +static void GetTileDesc_Bridge(TileIndex tile, TileDesc *td) +{ + td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; td->owner = GetTileOwner(tile); } -static void AnimateTile_TunnelBridge(TileIndex tile) +static void AnimateTile_Tunnel(TileIndex tile) { /* not used */ } -static void TileLoop_TunnelBridge(TileIndex tile) +static void AnimateTile_Bridge(TileIndex tile) { - bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelSnowOrDesert(tile) : HasBridgeSnowOrDesert(tile); + /* not used */ +} + +static void TileLoop_Tunnel(TileIndex tile) +{ + bool snow_or_desert = HasTunnelSnowOrDesert(tile); switch (_opt.landscape) { case LT_HILLY: if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { - if (IsTunnelTile(tile)) { - SetTunnelSnowOrDesert(tile, !snow_or_desert); - } else { - SetBridgeSnowOrDesert(tile, !snow_or_desert); - } + SetTunnelSnowOrDesert(tile, !snow_or_desert); MarkTileDirtyByTile(tile); } break; case LT_DESERT: if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { - if (IsTunnelTile(tile)) { - SetTunnelSnowOrDesert(tile, true); - } else { - SetBridgeSnowOrDesert(tile, true); - } + SetTunnelSnowOrDesert(tile, true); MarkTileDirtyByTile(tile); } break; } } -static void ClickTile_TunnelBridge(TileIndex tile) +static void TileLoop_Bridge(TileIndex tile) +{ + bool snow_or_desert = HasBridgeSnowOrDesert(tile); + switch (_opt.landscape) { + case LT_HILLY: + if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { + SetBridgeSnowOrDesert(tile, !snow_or_desert); + MarkTileDirtyByTile(tile); + } + break; + + case LT_DESERT: + if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { + SetBridgeSnowOrDesert(tile, true); + MarkTileDirtyByTile(tile); + } + break; + } +} + +static void ClickTile_Tunnel(TileIndex tile) +{ + /* not used */ +} + +static void ClickTile_Bridge(TileIndex tile) { /* not used */ } -static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode) +static uint32 GetTileTrackStatus_Tunnel(TileIndex tile, TransportType mode) { - if (IsTunnelTile(tile)) { - if (GetTunnelTransportType(tile) != mode) return 0; - return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; + if (GetTunnelTransportType(tile) != mode) return 0; + return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; +} + +static uint32 GetTileTrackStatus_Bridge(TileIndex tile, TransportType mode) +{ + if (GetBridgeTransportType(tile) != mode) return 0; + return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; +} + +static void ChangeTileOwner_Tunnel(TileIndex tile, PlayerID old_player, PlayerID new_player) +{ + if (!IsTileOwner(tile, old_player)) return; + + if (new_player != PLAYER_SPECTATOR) { + SetTileOwner(tile, new_player); } else { - if (GetBridgeTransportType(tile) != mode) return 0; - return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; + DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); } } -static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player) +static void ChangeTileOwner_Bridge(TileIndex tile, PlayerID old_player, PlayerID new_player) { if (!IsTileOwner(tile, old_player)) return; @@ -1180,137 +1257,159 @@ static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49}; -static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y) +static uint32 VehicleEnter_Tunnel(Vehicle *v, TileIndex tile, int x, int y) { int z = GetSlopeZ(x, y) - v->z_pos; + byte fc; + DiagDirection dir; + DiagDirection vdir; + if (myabs(z) > 2) return 8; - if (IsTunnelTile(tile)) { - byte fc; - DiagDirection dir; - DiagDirection vdir; - - if (v->type == VEH_Train) { - fc = (x & 0xF) + (y << 4); - - dir = GetTunnelDirection(tile); - vdir = DirToDiagDir(v->direction); + if (v->type == VEH_Train) { + fc = (x & 0xF) + (y << 4); - if (v->u.rail.track != 0x40 && dir == vdir) { - if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { - if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { - SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); - } - return 0; + dir = GetTunnelDirection(tile); + vdir = DirToDiagDir(v->direction); + + if (v->u.rail.track != 0x40 && dir == vdir) { + if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { + if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { + SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); } - if (fc == _tunnel_fractcoord_2[dir]) { - v->tile = tile; - v->u.rail.track = 0x40; - v->vehstatus |= VS_HIDDEN; - return 4; - } + return 0; } - - if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { - /* We're at the tunnel exit ?? */ + if (fc == _tunnel_fractcoord_2[dir]) { v->tile = tile; - v->u.rail.track = _exit_tunnel_track[dir]; - assert(v->u.rail.track); - v->vehstatus &= ~VS_HIDDEN; - return 4; - } - } else if (v->type == VEH_Road) { - fc = (x & 0xF) + (y << 4); - dir = GetTunnelDirection(tile); - vdir = DirToDiagDir(v->direction); - - // Enter tunnel? - if (v->u.road.state != 0xFF && dir == vdir) { - if (fc == _tunnel_fractcoord_4[dir] || - fc == _tunnel_fractcoord_5[dir]) { - v->tile = tile; - v->u.road.state = 0xFF; - v->vehstatus |= VS_HIDDEN; - return 4; - } else { - return 0; - } - } - - if (dir == ReverseDiagDir(vdir) && ( - /* We're at the tunnel exit ?? */ - fc == _tunnel_fractcoord_6[dir] || - fc == _tunnel_fractcoord_7[dir] - ) && - z == 0) { - v->tile = tile; - v->u.road.state = _road_exit_tunnel_state[dir]; - v->u.road.frame = _road_exit_tunnel_frame[dir]; - v->vehstatus &= ~VS_HIDDEN; + v->u.rail.track = 0x40; + v->vehstatus |= VS_HIDDEN; return 4; } } - } else if (IsBridgeTile(tile)) { // XXX is this necessary? - DiagDirection dir; - if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { - /* modify speed of vehicle */ - uint16 spd = _bridge[GetBridgeType(tile)].speed; + if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { + /* We're at the tunnel exit ?? */ + v->tile = tile; + v->u.rail.track = _exit_tunnel_track[dir]; + assert(v->u.rail.track); + v->vehstatus &= ~VS_HIDDEN; + return 4; + } + } else if (v->type == VEH_Road) { + fc = (x & 0xF) + (y << 4); + dir = GetTunnelDirection(tile); + vdir = DirToDiagDir(v->direction); - if (v->type == VEH_Road) spd *= 2; - if (v->cur_speed > spd) v->cur_speed = spd; + // Enter tunnel? + if (v->u.road.state != 0xFF && dir == vdir) { + if (fc == _tunnel_fractcoord_4[dir] || + fc == _tunnel_fractcoord_5[dir]) { + v->tile = tile; + v->u.road.state = 0xFF; + v->vehstatus |= VS_HIDDEN; + return 4; + } else { + return 0; + } } - dir = GetBridgeRampDirection(tile); - if (DirToDiagDir(v->direction) == dir) { - switch (dir) { - default: NOT_REACHED(); - case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; - case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; - case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; - case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break; - } - if (v->type == VEH_Train) { - v->u.rail.track = 0x40; - CLRBIT(v->u.rail.flags, VRF_GOINGUP); - CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); - } else { - v->u.road.state = 0xFF; - } + if (dir == ReverseDiagDir(vdir) && ( + /* We're at the tunnel exit ?? */ + fc == _tunnel_fractcoord_6[dir] || + fc == _tunnel_fractcoord_7[dir] + ) && + z == 0) { + v->tile = tile; + v->u.road.state = _road_exit_tunnel_state[dir]; + v->u.road.frame = _road_exit_tunnel_frame[dir]; + v->vehstatus &= ~VS_HIDDEN; return 4; - } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { - v->tile = tile; - if (v->type == VEH_Train) { - if (v->u.rail.track == 0x40) { - v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); - return 4; - } - } else { - if (v->u.road.state == 0xFF) { - v->u.road.state = _road_exit_tunnel_state[dir]; - v->u.road.frame = 0; - return 4; - } - } - return 0; } } return 0; } -const TileTypeProcs _tile_type_tunnelbridge_procs = { - DrawTile_TunnelBridge, /* draw_tile_proc */ - GetSlopeZ_TunnelBridge, /* get_slope_z_proc */ - ClearTile_TunnelBridge, /* clear_tile_proc */ - GetAcceptedCargo_TunnelBridge, /* get_accepted_cargo_proc */ - GetTileDesc_TunnelBridge, /* get_tile_desc_proc */ - GetTileTrackStatus_TunnelBridge, /* get_tile_track_status_proc */ - ClickTile_TunnelBridge, /* click_tile_proc */ - AnimateTile_TunnelBridge, /* animate_tile_proc */ - TileLoop_TunnelBridge, /* tile_loop_clear */ - ChangeTileOwner_TunnelBridge, /* change_tile_owner_clear */ +static uint32 VehicleEnter_Bridge(Vehicle *v, TileIndex tile, int x, int y) +{ + int z = GetSlopeZ(x, y) - v->z_pos; + + DiagDirection dir; + + if (myabs(z) > 2) return 8; + + if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { + /* modify speed of vehicle */ + uint16 spd = _bridge[GetBridgeType(tile)].speed; + + if (v->type == VEH_Road) spd *= 2; + if (v->cur_speed > spd) v->cur_speed = spd; + } + + dir = GetBridgeRampDirection(tile); + if (DirToDiagDir(v->direction) == dir) { + switch (dir) { + default: NOT_REACHED(); + case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; + case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; + case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; + case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break; + } + if (v->type == VEH_Train) { + v->u.rail.track = 0x40; + CLRBIT(v->u.rail.flags, VRF_GOINGUP); + CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); + } else { + v->u.road.state = 0xFF; + } + return 4; + } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { + v->tile = tile; + if (v->type == VEH_Train) { + if (v->u.rail.track == 0x40) { + v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); + return 4; + } + } else { + if (v->u.road.state == 0xFF) { + v->u.road.state = _road_exit_tunnel_state[dir]; + v->u.road.frame = 0; + return 4; + } + } + return 0; + } + return 0; +} + +const TileTypeProcs _tile_type_tunnel_procs = { + DrawTile_Tunnel, /* draw_tile_proc */ + GetSlopeZ_Tunnel, /* get_slope_z_proc */ + ClearTile_Tunnel, /* clear_tile_proc */ + GetAcceptedCargo_Tunnel, /* get_accepted_cargo_proc */ + GetTileDesc_Tunnel, /* get_tile_desc_proc */ + GetTileTrackStatus_Tunnel, /* get_tile_track_status_proc */ + ClickTile_Tunnel, /* click_tile_proc */ + AnimateTile_Tunnel, /* animate_tile_proc */ + TileLoop_Tunnel, /* tile_loop_clear */ + ChangeTileOwner_Tunnel, /* change_tile_owner_clear */ NULL, /* get_produced_cargo_proc */ - VehicleEnter_TunnelBridge, /* vehicle_enter_tile_proc */ - GetSlopeTileh_TunnelBridge, /* get_slope_tileh_proc */ + VehicleEnter_Tunnel, /* vehicle_enter_tile_proc */ + GetSlopeTileh_Tunnel, /* get_slope_tileh_proc */ }; + +const TileTypeProcs _tile_type_bridge_procs = { + DrawTile_Bridge, /* draw_tile_proc */ + GetSlopeZ_Bridge, /* get_slope_z_proc */ + ClearTile_Bridge, /* clear_tile_proc */ + GetAcceptedCargo_Bridge, /* get_accepted_cargo_proc */ + GetTileDesc_Bridge, /* get_tile_desc_proc */ + GetTileTrackStatus_Bridge, /* get_tile_track_status_proc */ + ClickTile_Bridge, /* click_tile_proc */ + AnimateTile_Bridge, /* animate_tile_proc */ + TileLoop_Bridge, /* tile_loop_clear */ + ChangeTileOwner_Bridge, /* change_tile_owner_clear */ + NULL, /* get_produced_cargo_proc */ + VehicleEnter_Bridge, /* vehicle_enter_tile_proc */ + GetSlopeTileh_Bridge, /* get_slope_tileh_proc */ +};