764 |
764 |
765 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
765 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
766 return bridge_speed; |
766 return bridge_speed; |
767 } |
767 } |
768 |
768 |
|
769 static bool IsCustomBridgeHead(TileIndex tile) |
|
770 { |
|
771 assert(IsBridgeTile(tile)); |
|
772 |
|
773 if (IsTileType(tile, MP_RAILWAY_BRIDGE)) { |
|
774 return !(GetTrackBits(tile) == TRACK_BIT_X || GetTrackBits(tile) == TRACK_BIT_Y); |
|
775 } |
|
776 |
|
777 return false; /* TODO - street bridges */ |
|
778 } |
|
779 |
769 |
780 |
770 /** Gets the absolute z coordinate of a point inside a bridge tile |
781 /** Gets the absolute z coordinate of a point inside a bridge tile |
771 * When we're on the track (that means between position 5 and 10) |
782 * When we're on the track (that means between position 5 and 10) |
772 * on the coordinate perpendicular to the track it returns the base |
783 * on the coordinate perpendicular to the track it returns the base |
773 * height of the ramp |
784 * height of the ramp |
774 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
785 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
775 * "true" Z coordinate of the tile by taking the slope into account |
786 * "true" Z coordinate of the tile by taking the slope into account |
|
787 * For custom bridge heads the entire bridge head is flat and has the |
|
788 * same z coordinate |
776 * @param tile The index of the tile we are talking about |
789 * @param tile The index of the tile we are talking about |
777 * @param x Absolute or relative x coordinate |
790 * @param x Absolute or relative x coordinate |
778 * @param y Absolute or relative y coordinate |
791 * @param y Absolute or relative y coordinate |
779 * @return Absolute z coordinate |
792 * @return Absolute z coordinate |
780 */ |
793 */ |
787 x &= 0xF; |
800 x &= 0xF; |
788 y &= 0xF; |
801 y &= 0xF; |
789 |
802 |
790 pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); |
803 pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); |
791 |
804 |
792 // On the bridge ramp? |
805 // On the bridge ramp or flat bridge head? |
793 if (5 <= pos && pos <= 10) { |
806 if ( (5 <= pos && pos <= 10) || IsCustomBridgeHead(tile)) { |
794 uint delta; |
807 uint delta; |
795 |
808 |
796 if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; |
809 if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; |
797 |
810 |
798 if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; |
811 if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; |
935 { |
948 { |
936 int z = GetSlopeZ(x, y) - v->z_pos; |
949 int z = GetSlopeZ(x, y) - v->z_pos; |
937 |
950 |
938 DiagDirection dir; |
951 DiagDirection dir; |
939 |
952 |
|
953 if (IsCustomBridgeHead(tile)) { |
|
954 uint h; |
|
955 GetTileSlope(tile, &h); |
|
956 |
|
957 z = h + TILE_HEIGHT - v->z_pos; |
|
958 } |
|
959 |
940 if (myabs(z) > 2) return 8; |
960 if (myabs(z) > 2) return 8; |
941 |
961 |
942 if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { |
962 if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { |
943 /* modify speed of vehicle */ |
963 /* modify speed of vehicle */ |
944 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
964 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
946 if (v->type == VEH_Road) spd *= 2; |
966 if (v->type == VEH_Road) spd *= 2; |
947 if (v->cur_speed > spd) v->cur_speed = spd; |
967 if (v->cur_speed > spd) v->cur_speed = spd; |
948 } |
968 } |
949 |
969 |
950 dir = GetBridgeRampDirection(tile); |
970 dir = GetBridgeRampDirection(tile); |
951 if (DirToDiagDir(v->direction) == dir) { |
971 if (DirToDiagDir(v->direction) == dir || IsTileType(tile, MP_RAILWAY_BRIDGE)) { |
952 switch (dir) { |
972 switch (dir) { |
953 default: NOT_REACHED(); |
973 default: NOT_REACHED(); |
954 case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; |
974 case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; |
955 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; |
975 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; |
956 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; |
976 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; |