222 |
222 |
223 if (flags & DC_EXEC) { |
223 if (flags & DC_EXEC) { |
224 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
224 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
225 |
225 |
226 _m[tile].m5 ^= c; |
226 _m[tile].m5 ^= c; |
227 if (GB(_m[tile].m5, 0, 4) == 0) { |
227 if (GetRoadBits(tile) == 0) { |
228 DoClearSquare(tile); |
228 DoClearSquare(tile); |
229 } else { |
229 } else { |
230 MarkTileDirtyByTile(tile); |
230 MarkTileDirtyByTile(tile); |
231 } |
231 } |
232 } |
232 } |
268 return_cmd_error(INVALID_STRING_ID); |
268 return_cmd_error(INVALID_STRING_ID); |
269 } |
269 } |
270 } |
270 } |
271 |
271 |
272 |
272 |
273 static const byte _valid_tileh_slopes_road[3][15] = { |
273 static const RoadBits _valid_tileh_slopes_road[3][15] = { |
274 // set of normal ones |
274 // set of normal ones |
275 { |
275 { |
276 ROAD_ALL, 0, 0, |
276 ROAD_ALL, 0, 0, |
277 ROAD_SW | ROAD_NE, 0, 0, // 3, 4, 5 |
277 ROAD_X, 0, 0, // 3, 4, 5 |
278 ROAD_NW | ROAD_SE, 0, 0, |
278 ROAD_Y, 0, 0, |
279 ROAD_NW | ROAD_SE, 0, 0, // 9, 10, 11 |
279 ROAD_Y, 0, 0, // 9, 10, 11 |
280 ROAD_SW | ROAD_NE, 0, 0 |
280 ROAD_X, 0, 0 |
281 }, |
281 }, |
282 // allowed road for an evenly raised platform |
282 // allowed road for an evenly raised platform |
283 { |
283 { |
284 0, |
284 0, |
285 ROAD_SW | ROAD_NW, |
285 ROAD_SW | ROAD_NW, |
286 ROAD_SW | ROAD_SE, |
286 ROAD_SW | ROAD_SE, |
287 ROAD_NW | ROAD_SE | ROAD_SW, |
287 ROAD_Y | ROAD_SW, |
288 |
288 |
289 ROAD_SE | ROAD_NE, // 4 |
289 ROAD_SE | ROAD_NE, // 4 |
290 ROAD_ALL, |
290 ROAD_ALL, |
291 ROAD_SW | ROAD_NE | ROAD_SE, |
291 ROAD_X | ROAD_SE, |
292 ROAD_ALL, |
292 ROAD_ALL, |
293 |
293 |
294 ROAD_NW | ROAD_NE, // 8 |
294 ROAD_NW | ROAD_NE, // 8 |
295 ROAD_SW | ROAD_NE | ROAD_NW, |
295 ROAD_X | ROAD_NW, |
296 ROAD_ALL, |
296 ROAD_ALL, |
297 ROAD_ALL, |
297 ROAD_ALL, |
298 |
298 |
299 ROAD_NW | ROAD_SE | ROAD_NE, // 12 |
299 ROAD_Y | ROAD_NE, // 12 |
300 ROAD_ALL, |
300 ROAD_ALL, |
301 ROAD_ALL |
301 ROAD_ALL |
302 }, |
302 }, |
303 // valid railway crossings on slopes |
303 // valid railway crossings on slopes |
304 { |
304 { |
547 |
547 |
548 cost = 0; |
548 cost = 0; |
549 tile = start_tile; |
549 tile = start_tile; |
550 // Start tile is the small number. |
550 // Start tile is the small number. |
551 for (;;) { |
551 for (;;) { |
552 uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE; |
552 RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X; |
|
553 |
553 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
554 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
554 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
555 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
555 |
556 |
556 ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD); |
557 ret = DoCommandByTile(tile, bits, 0, flags, CMD_BUILD_ROAD); |
557 if (CmdFailed(ret)) { |
558 if (CmdFailed(ret)) { |
602 |
603 |
603 cost = 0; |
604 cost = 0; |
604 tile = start_tile; |
605 tile = start_tile; |
605 // Start tile is the small number. |
606 // Start tile is the small number. |
606 for (;;) { |
607 for (;;) { |
607 uint bits = HASBIT(p2, 2) ? ROAD_SE | ROAD_NW : ROAD_SW | ROAD_NE; |
608 RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X; |
|
609 |
608 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
610 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
609 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
611 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
610 |
612 |
611 // try to remove the halves. |
613 // try to remove the halves. |
612 if (bits) { |
614 if (bits != 0) { |
613 ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD); |
615 ret = DoCommandByTile(tile, bits, 0, flags, CMD_REMOVE_ROAD); |
614 if (!CmdFailed(ret)) cost += ret; |
616 if (!CmdFailed(ret)) cost += ret; |
615 } |
617 } |
616 |
618 |
617 if (tile == end_tile) break; |
619 if (tile == end_tile) break; |
667 dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
669 dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
668 |
670 |
669 ModifyTile(tile, |
671 ModifyTile(tile, |
670 MP_SETTYPE(MP_STREET) | |
672 MP_SETTYPE(MP_STREET) | |
671 MP_MAPOWNER_CURRENT | MP_MAP5, |
673 MP_MAPOWNER_CURRENT | MP_MAP5, |
672 (p1 | 0x20) /* map5 */ |
674 (ROAD_DEPOT << 4) | p1 /* map5 */ |
673 ); |
675 ); |
674 |
676 |
675 } |
677 } |
676 return cost + _price.build_road_depot; |
678 return cost + _price.build_road_depot; |
677 } |
679 } |
756 (i = 0, tileh == 1) || |
758 (i = 0, tileh == 1) || |
757 (i += 2, tileh == 2) || |
759 (i += 2, tileh == 2) || |
758 (i += 2, tileh == 4) || |
760 (i += 2, tileh == 4) || |
759 (i += 2, tileh == 8) |
761 (i += 2, tileh == 8) |
760 ) && ( |
762 ) && ( |
761 ( bits == (ROAD_SW | ROAD_NE)) || |
763 ( bits == ROAD_X) || |
762 (i++, bits == (ROAD_NW | ROAD_SE)) |
764 (i++, bits == ROAD_Y) |
763 )) { |
765 )) { |
764 return i + 15; |
766 return i + 15; |
765 } |
767 } |
766 |
768 |
767 return 0; |
769 return 0; |
780 * @param road RoadBits to draw |
782 * @param road RoadBits to draw |
781 * @param ground_type Ground type |
783 * @param ground_type Ground type |
782 * @param snow Draw snow |
784 * @param snow Draw snow |
783 * @param flat Draw foundation |
785 * @param flat Draw foundation |
784 */ |
786 */ |
785 static void DrawRoadBits(TileInfo *ti, byte road, byte ground_type, bool snow, bool flat) |
787 static void DrawRoadBits(TileInfo* ti, RoadBits road, byte ground_type, bool snow, bool flat) |
786 { |
788 { |
787 const DrawRoadTileStruct *drts; |
789 const DrawRoadTileStruct *drts; |
788 PalSpriteID image = 0; |
790 PalSpriteID image = 0; |
789 |
791 |
790 if (ti->tileh != 0) { |
792 if (ti->tileh != 0) { |
818 // Return if full detail is disabled, or we are zoomed fully out. |
820 // Return if full detail is disabled, or we are zoomed fully out. |
819 if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return; |
821 if (!(_display_opt & DO_FULL_DETAIL) || _cur_dpi->zoom == 2) return; |
820 |
822 |
821 if (ground_type >= 6) { |
823 if (ground_type >= 6) { |
822 // Road works |
824 // Road works |
823 DrawGroundSprite(HASBIT(road, 3) ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y); |
825 DrawGroundSprite(road & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y); |
824 return; |
826 return; |
825 } |
827 } |
826 |
828 |
827 // Draw extra details. |
829 // Draw extra details. |
828 for (drts = _road_display_table[ground_type][road]; drts->image != 0; drts++) { |
830 for (drts = _road_display_table[ground_type][road]; drts->image != 0; drts++) { |
837 static void DrawTile_Road(TileInfo *ti) |
839 static void DrawTile_Road(TileInfo *ti) |
838 { |
840 { |
839 PalSpriteID image; |
841 PalSpriteID image; |
840 uint16 m2; |
842 uint16 m2; |
841 |
843 |
842 switch (GB(ti->map5, 4, 4)) { |
844 switch (GetRoadType(ti->tile)) { |
843 case 0: // normal road |
845 case ROAD_NORMAL: |
844 DrawRoadBits(ti, GB(ti->map5, 0, 4), GB(_m[ti->tile].m4, 4, 3), HASBIT(_m[ti->tile].m4, 7), false); |
846 DrawRoadBits(ti, GetRoadBits(ti->tile), GB(_m[ti->tile].m4, 4, 3), HASBIT(_m[ti->tile].m4, 7), false); |
845 break; |
847 break; |
846 |
848 |
847 case 1: { // level crossing |
849 case ROAD_CROSSING: { |
848 if (ti->tileh != 0) DrawFoundation(ti, ti->tileh); |
850 if (ti->tileh != 0) DrawFoundation(ti, ti->tileh); |
849 |
851 |
850 image = GetRailTypeInfo(GB(_m[ti->tile].m4, 0, 4))->base_sprites.crossing; |
852 image = GetRailTypeInfo(GB(_m[ti->tile].m4, 0, 4))->base_sprites.crossing; |
851 |
853 |
852 if (GB(ti->map5, 3, 1) == 0) image++; /* direction */ |
854 if (GB(ti->map5, 3, 1) == 0) image++; /* direction */ |
924 uint z = ti->z; |
927 uint z = ti->z; |
925 int th = ti->tileh; |
928 int th = ti->tileh; |
926 |
929 |
927 // check if it's a foundation |
930 // check if it's a foundation |
928 if (ti->tileh != 0) { |
931 if (ti->tileh != 0) { |
929 switch (GB(ti->map5, 4, 4)) { |
932 switch (GetRoadType(ti->tile)) { |
930 case 0: { // normal road |
933 case ROAD_NORMAL: { |
931 uint f = GetRoadFoundation(ti->tileh, GB(ti->map5, 0, 4)); |
934 uint f = GetRoadFoundation(ti->tileh, GetRoadBits(ti->tile)); |
|
935 |
932 if (f != 0) { |
936 if (f != 0) { |
933 if (f < 15) { |
937 if (f < 15) { |
934 // leveled foundation |
938 // leveled foundation |
935 return z + 8; |
939 return z + 8; |
936 } |
940 } |
954 |
958 |
955 static uint GetSlopeTileh_Road(const TileInfo *ti) |
959 static uint GetSlopeTileh_Road(const TileInfo *ti) |
956 { |
960 { |
957 // check if it's a foundation |
961 // check if it's a foundation |
958 if (ti->tileh != 0) { |
962 if (ti->tileh != 0) { |
959 switch (GB(ti->map5, 4, 4)) { |
963 switch (GetRoadType(ti->tile)) { |
960 case 0: { // normal road |
964 case ROAD_NORMAL: { |
961 uint f = GetRoadFoundation(ti->tileh, GB(ti->map5, 0, 4)); |
965 uint f = GetRoadFoundation(ti->tileh, GetRoadBits(ti->tile)); |
|
966 |
962 if (f != 0) { |
967 if (f != 0) { |
963 if (f < 15) { |
968 if (f < 15) { |
964 // leveled foundation |
969 // leveled foundation |
965 return 0; |
970 return 0; |
966 } |
971 } |
1211 |
1216 |
1212 case ROAD_CROSSING: |
1217 case ROAD_CROSSING: |
1213 SetTileOwner(tile, _m[tile].m3); |
1218 SetTileOwner(tile, _m[tile].m3); |
1214 _m[tile].m3 = 0; |
1219 _m[tile].m3 = 0; |
1215 _m[tile].m4 &= 0x80; |
1220 _m[tile].m4 &= 0x80; |
1216 _m[tile].m5 = GetCrossingRoadBits(tile); |
1221 _m[tile].m5 = (ROAD_NORMAL << 4) | GetCrossingRoadBits(tile); |
1217 break; |
1222 break; |
1218 |
1223 |
1219 default: |
1224 default: |
1220 case ROAD_DEPOT: |
1225 case ROAD_DEPOT: |
1221 DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
1226 DoCommandByTile(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |