39 if (r & ROAD_NE) ++count; |
39 if (r & ROAD_NE) ++count; |
40 return count; |
40 return count; |
41 } |
41 } |
42 |
42 |
43 |
43 |
44 bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road) |
44 bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt) |
45 { |
45 { |
46 RoadBits present; |
46 RoadBits present; |
47 RoadBits n; |
47 RoadBits n; |
48 *edge_road = true; |
48 *edge_road = true; |
49 |
49 |
50 if (_game_mode == GM_EDITOR) return true; |
50 if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return true; |
51 |
51 |
52 /* Only do the special processing for actual players. */ |
52 /* Only do the special processing for actual players. */ |
53 if (!IsValidPlayer(_current_player)) return true; |
53 if (!IsValidPlayer(_current_player)) return true; |
54 |
54 |
55 /* Only do the special processing if the road is owned |
55 /* Only do the special processing if the road is owned |
58 |
58 |
59 if (_cheats.magic_bulldozer.value) return true; |
59 if (_cheats.magic_bulldozer.value) return true; |
60 |
60 |
61 /* Get a bitmask of which neighbouring roads has a tile */ |
61 /* Get a bitmask of which neighbouring roads has a tile */ |
62 n = ROAD_NONE; |
62 n = ROAD_NONE; |
63 present = GetAnyRoadBits(tile); |
63 present = GetAnyRoadBits(tile, rt); |
64 if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0)) & ROAD_SW) n |= ROAD_NE; |
64 if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0), rt) & ROAD_SW) n |= ROAD_NE; |
65 if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE; |
65 if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1), rt) & ROAD_NW) n |= ROAD_SE; |
66 if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW; |
66 if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rt) & ROAD_NE) n |= ROAD_SW; |
67 if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1)) & ROAD_SE) n |= ROAD_NW; |
67 if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rt) & ROAD_SE) n |= ROAD_NW; |
68 |
68 |
69 /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, |
69 /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, |
70 * then allow it */ |
70 * then allow it */ |
71 if ((n & (n - 1)) != 0 && (n & remove) != 0) { |
71 if ((n & (n - 1)) != 0 && (n & remove) != 0) { |
72 Town *t; |
72 Town *t; |
82 } |
82 } |
83 |
83 |
84 return true; |
84 return true; |
85 } |
85 } |
86 |
86 |
87 static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road) |
87 static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road, RoadType rt) |
88 { |
88 { |
89 return CheckAllowRemoveRoad(tile, remove, IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile), edge_road); |
89 return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt); |
90 } |
90 } |
91 |
91 |
92 /** Delete a piece of road. |
92 /** Delete a piece of road. |
93 * @param tile tile where to remove road from |
93 * @param tile tile where to remove road from |
94 * @param flags operation to perform |
94 * @param flags operation to perform |
95 * @param p1 bit 0..3 road pieces to remove (RoadBits) |
95 * @param p1 bit 0..3 road pieces to remove (RoadBits) |
|
96 * bit 4..5 road type |
96 * @param p2 unused |
97 * @param p2 unused |
97 */ |
98 */ |
98 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
99 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
99 { |
100 { |
100 /* cost for removing inner/edge -roads */ |
101 /* cost for removing inner/edge -roads */ |
101 static const uint16 road_remove_cost[2] = {50, 18}; |
102 static const uint16 road_remove_cost[2] = {50, 18}; |
102 |
103 |
103 Owner owner; |
|
104 Town *t; |
104 Town *t; |
105 /* true if the roadpiece was always removeable, |
105 /* true if the roadpiece was always removeable, |
106 * false if it was a center piece. Affects town ratings drop */ |
106 * false if it was a center piece. Affects town ratings drop */ |
107 bool edge_road; |
107 bool edge_road; |
108 |
108 |
109 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
109 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
110 |
110 |
111 if (!IsTileType(tile, MP_STREET)) return CMD_ERROR; |
111 RoadType rt = (RoadType)GB(p1, 4, 2); |
112 |
112 if (!IsTileType(tile, MP_STREET) || !IsValidRoadType(rt)) return CMD_ERROR; |
113 owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile); |
113 |
|
114 Owner owner = GetRoadOwner(tile, rt); |
114 |
115 |
115 if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) { |
116 if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) { |
116 t = GetTownByTile(tile); |
117 t = GetTownByTile(tile); |
117 } else { |
118 } else { |
118 t = NULL; |
119 t = NULL; |
119 } |
120 } |
120 |
121 |
121 RoadBits pieces = Extract<RoadBits, 0>(p1); |
122 RoadBits pieces = Extract<RoadBits, 0>(p1); |
122 |
123 RoadTypes rts = GetRoadTypes(tile); |
123 if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR; |
124 /* The tile doesn't have the given road type */ |
|
125 if (!HASBIT(rts, rt)) return CMD_ERROR; |
|
126 |
|
127 if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR; |
124 |
128 |
125 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
129 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
126 |
130 |
127 /* check if you're allowed to remove the street owned by a town |
131 /* check if you're allowed to remove the street owned by a town |
128 * removal allowance depends on difficulty setting */ |
132 * removal allowance depends on difficulty setting */ |
129 if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; |
133 if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; |
130 |
134 |
131 switch (GetRoadTileType(tile)) { |
135 switch (GetRoadTileType(tile)) { |
132 case ROAD_TILE_NORMAL: { |
136 case ROAD_TILE_NORMAL: { |
133 RoadBits present = GetRoadBits(tile); |
137 RoadBits present = GetRoadBits(tile, rt); |
134 RoadBits c = pieces; |
138 RoadBits c = pieces; |
135 |
139 |
136 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
140 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
137 |
141 |
138 if (GetTileSlope(tile, NULL) != SLOPE_FLAT && |
142 if (GetTileSlope(tile, NULL) != SLOPE_FLAT && |
148 if (flags & DC_EXEC) { |
152 if (flags & DC_EXEC) { |
149 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
153 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
150 |
154 |
151 present ^= c; |
155 present ^= c; |
152 if (present == 0) { |
156 if (present == 0) { |
153 DoClearSquare(tile); |
157 RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); |
|
158 if (rts == ROADTYPES_NONE) { |
|
159 DoClearSquare(tile); |
|
160 } else { |
|
161 SetRoadTypes(tile, rts); |
|
162 } |
154 } else { |
163 } else { |
155 SetRoadBits(tile, present); |
164 SetRoadBits(tile, present, rt); |
156 MarkTileDirtyByTile(tile); |
165 MarkTileDirtyByTile(tile); |
157 } |
166 } |
158 } |
167 } |
159 return CountRoadBits(c) * _price.remove_road; |
168 return CountRoadBits(c) * _price.remove_road; |
160 } |
169 } |
163 if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) { |
172 if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) { |
164 return CMD_ERROR; |
173 return CMD_ERROR; |
165 } |
174 } |
166 |
175 |
167 if (flags & DC_EXEC) { |
176 if (flags & DC_EXEC) { |
168 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
177 if (rt == ROADTYPE_ROAD) { |
169 |
178 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
170 MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile)); |
179 } |
|
180 |
|
181 RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); |
|
182 if (rts == ROADTYPES_NONE) { |
|
183 MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile)); |
|
184 } else { |
|
185 SetRoadTypes(tile, rts); |
|
186 } |
171 MarkTileDirtyByTile(tile); |
187 MarkTileDirtyByTile(tile); |
172 YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); |
188 YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); |
173 } |
189 } |
174 return _price.remove_road * 2; |
190 return _price.remove_road * 2; |
175 } |
191 } |
269 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero |
286 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero |
270 * if a non-player is building the road */ |
287 * if a non-player is building the road */ |
271 if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR; |
288 if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR; |
272 |
289 |
273 RoadBits pieces = Extract<RoadBits, 0>(p1); |
290 RoadBits pieces = Extract<RoadBits, 0>(p1); |
|
291 |
|
292 RoadType rt = (RoadType)GB(p1, 4, 2); |
|
293 if (!IsValidRoadType(rt)) return CMD_ERROR; |
274 |
294 |
275 tileh = GetTileSlope(tile, NULL); |
295 tileh = GetTileSlope(tile, NULL); |
276 |
296 |
277 switch (GetTileType(tile)) { |
297 switch (GetTileType(tile)) { |
278 case MP_STREET: |
298 case MP_STREET: |
279 switch (GetRoadTileType(tile)) { |
299 switch (GetRoadTileType(tile)) { |
280 case ROAD_TILE_NORMAL: |
300 case ROAD_TILE_NORMAL: |
281 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
301 if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS); |
282 |
302 |
283 existing = GetRoadBits(tile); |
303 existing = GetRoadBits(tile, rt); |
284 if ((existing & pieces) == pieces) { |
304 if ((existing & pieces) == pieces) { |
285 return_cmd_error(STR_1007_ALREADY_BUILT); |
305 return_cmd_error(STR_1007_ALREADY_BUILT); |
286 } |
306 } |
287 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
307 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
288 break; |
308 break; |
289 |
309 |
290 case ROAD_TILE_CROSSING: |
310 case ROAD_TILE_CROSSING: |
291 if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct? |
311 if (HASBIT(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT); |
292 return_cmd_error(STR_1007_ALREADY_BUILT); |
312 if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) goto do_clear; |
293 } |
313 break; |
294 goto do_clear; |
|
295 |
314 |
296 default: |
315 default: |
297 case ROAD_TILE_DEPOT: |
316 case ROAD_TILE_DEPOT: |
298 goto do_clear; |
317 goto do_clear; |
299 } |
318 } |
330 |
349 |
331 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
350 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
332 |
351 |
333 if (flags & DC_EXEC) { |
352 if (flags & DC_EXEC) { |
334 YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); |
353 YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); |
335 MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2); |
354 MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt), p2); |
336 MarkTileDirtyByTile(tile); |
355 MarkTileDirtyByTile(tile); |
337 } |
356 } |
338 return _price.build_road * 2; |
357 return _price.build_road * 2; |
339 } |
358 } |
340 |
359 |
360 |
379 |
361 cost += CountRoadBits(pieces) * _price.build_road; |
380 cost += CountRoadBits(pieces) * _price.build_road; |
362 |
381 |
363 if (flags & DC_EXEC) { |
382 if (flags & DC_EXEC) { |
364 if (IsTileType(tile, MP_STREET)) { |
383 if (IsTileType(tile, MP_STREET)) { |
365 SetRoadBits(tile, existing | pieces); |
384 if (existing == 0) { |
|
385 SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); |
|
386 SetRoadOwner(tile, rt, _current_player); |
|
387 } |
|
388 SetRoadBits(tile, existing | pieces, rt); |
366 } else { |
389 } else { |
367 MakeRoadNormal(tile, _current_player, pieces, p2); |
390 MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player); |
368 } |
391 } |
369 |
392 |
370 MarkTileDirtyByTile(tile); |
393 MarkTileDirtyByTile(tile); |
371 } |
394 } |
372 return cost; |
395 return cost; |
409 * @param p1 start tile of drag |
432 * @param p1 start tile of drag |
410 * @param p2 various bitstuffed elements |
433 * @param p2 various bitstuffed elements |
411 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) |
434 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) |
412 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) |
435 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) |
413 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) |
436 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) |
|
437 * - p2 = (bit 3) - road type |
414 */ |
438 */ |
415 int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
439 int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
416 { |
440 { |
417 TileIndex start_tile, tile; |
441 TileIndex start_tile, tile; |
418 int32 cost, ret; |
442 int32 cost, ret; |
442 RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X; |
467 RoadBits bits = HASBIT(p2, 2) ? ROAD_Y : ROAD_X; |
443 |
468 |
444 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
469 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
445 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
470 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
446 |
471 |
447 ret = DoCommand(tile, bits, 0, flags, CMD_BUILD_ROAD); |
472 ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); |
448 if (CmdFailed(ret)) { |
473 if (CmdFailed(ret)) { |
449 if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR; |
474 if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR; |
450 _error_message = INVALID_STRING_ID; |
475 _error_message = INVALID_STRING_ID; |
451 } else { |
476 } else { |
452 cost += ret; |
477 cost += ret; |
466 * @param p1 start tile of drag |
491 * @param p1 start tile of drag |
467 * @param p2 various bitstuffed elements |
492 * @param p2 various bitstuffed elements |
468 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) |
493 * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) |
469 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) |
494 * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) |
470 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) |
495 * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) |
|
496 * - p2 = (bit 3) - road type |
471 */ |
497 */ |
472 int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
498 int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
473 { |
499 { |
474 TileIndex start_tile, tile; |
500 TileIndex start_tile, tile; |
475 int32 cost, ret; |
501 int32 cost, ret; |
501 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
528 if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE; |
502 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
529 if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW; |
503 |
530 |
504 /* try to remove the halves. */ |
531 /* try to remove the halves. */ |
505 if (bits != 0) { |
532 if (bits != 0) { |
506 ret = DoCommand(tile, bits, 0, flags, CMD_REMOVE_ROAD); |
533 ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD); |
507 if (!CmdFailed(ret)) cost += ret; |
534 if (!CmdFailed(ret)) cost += ret; |
508 } |
535 } |
509 |
536 |
510 if (tile == end_tile) break; |
537 if (tile == end_tile) break; |
511 |
538 |
575 |
604 |
576 static int32 ClearTile_Road(TileIndex tile, byte flags) |
605 static int32 ClearTile_Road(TileIndex tile, byte flags) |
577 { |
606 { |
578 switch (GetRoadTileType(tile)) { |
607 switch (GetRoadTileType(tile)) { |
579 case ROAD_TILE_NORMAL: { |
608 case ROAD_TILE_NORMAL: { |
580 RoadBits b = GetRoadBits(tile); |
609 RoadBits b = GetAllRoadBits(tile); |
581 |
610 |
582 #define M(x) (1 << (x)) |
611 #define M(x) (1 << (x)) |
583 /* Clear the road if only one piece is on the tile OR the AI tries |
612 /* Clear the road if only one piece is on the tile OR the AI tries |
584 * to clear town road OR we are not using the DC_AUTO flag */ |
613 * to clear town road OR we are not using the DC_AUTO flag */ |
585 if ((M(b) & (M(ROAD_NW) | M(ROAD_SW) | M(ROAD_SE) | M(ROAD_NE))) || |
614 if ((M(b) & (M(ROAD_NW) | M(ROAD_SW) | M(ROAD_SE) | M(ROAD_NE))) || |
854 |
883 |
855 static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh) |
884 static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh) |
856 { |
885 { |
857 if (tileh == SLOPE_FLAT) return SLOPE_FLAT; |
886 if (tileh == SLOPE_FLAT) return SLOPE_FLAT; |
858 if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { |
887 if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) { |
859 uint f = GetRoadFoundation(tileh, GetRoadBits(tile)); |
888 uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile)); |
860 |
889 |
861 if (f == 0) return tileh; |
890 if (f == 0) return tileh; |
862 if (f < 15) return SLOPE_FLAT; // leveled foundation |
891 if (f < 15) return SLOPE_FLAT; // leveled foundation |
863 return _inclined_tileh[f - 15]; // inclined foundation |
892 return _inclined_tileh[f - 15]; // inclined foundation |
864 } else { |
893 } else { |
922 grp = GetTownRadiusGroup(t, tile); |
951 grp = GetTownRadiusGroup(t, tile); |
923 |
952 |
924 /* Show an animation to indicate road work */ |
953 /* Show an animation to indicate road work */ |
925 if (t->road_build_months != 0 && |
954 if (t->road_build_months != 0 && |
926 (DistanceManhattan(t->xy, tile) < 8 || grp != 0) && |
955 (DistanceManhattan(t->xy, tile) < 8 || grp != 0) && |
927 GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) { |
956 GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) { |
928 if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) { |
957 if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) { |
929 StartRoadWorks(tile); |
958 StartRoadWorks(tile); |
930 |
959 |
931 SndPlayTileFx(SND_21_JACKHAMMER, tile); |
960 SndPlayTileFx(SND_21_JACKHAMMER, tile); |
932 CreateEffectVehicleAbove( |
961 CreateEffectVehicleAbove( |
976 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F, |
1005 0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F, |
977 }; |
1006 }; |
978 |
1007 |
979 static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode) |
1008 static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode) |
980 { |
1009 { |
|
1010 RoadType rt = ROADTYPE_ROAD; |
|
1011 |
981 switch (mode) { |
1012 switch (mode) { |
982 case TRANSPORT_RAIL: |
1013 case TRANSPORT_RAIL: |
983 if (!IsLevelCrossing(tile)) return 0; |
1014 if (!IsLevelCrossing(tile)) return 0; |
984 return GetCrossingRailBits(tile) * 0x101; |
1015 return GetCrossingRailBits(tile) * 0x101; |
985 |
1016 |
986 case TRANSPORT_ROAD: |
1017 case TRANSPORT_ROAD: |
|
1018 if (!HASBIT(GetRoadTypes(tile), rt)) return 0; |
987 switch (GetRoadTileType(tile)) { |
1019 switch (GetRoadTileType(tile)) { |
988 case ROAD_TILE_NORMAL: |
1020 case ROAD_TILE_NORMAL: |
989 return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101; |
1021 return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * 0x101; |
990 |
1022 |
991 case ROAD_TILE_CROSSING: { |
1023 case ROAD_TILE_CROSSING: { |
992 uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101; |
1024 uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101; |
993 |
1025 |
994 if (IsCrossingBarred(tile)) r *= 0x10001; |
1026 if (IsCrossingBarred(tile)) r *= 0x10001; |
1058 } |
1090 } |
1059 |
1091 |
1060 |
1092 |
1061 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1093 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1062 { |
1094 { |
1063 if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) == old_player) { |
1095 if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) { |
1064 SetCrossingRoadOwner(tile, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player); |
1096 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
1065 } |
1097 return; |
1066 |
1098 } |
1067 if (!IsTileOwner(tile, old_player)) return; |
1099 |
1068 |
1100 for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { |
1069 if (new_player != PLAYER_SPECTATOR) { |
1101 if (!HASBIT(GetRoadTypes(tile), rt)) continue; |
1070 SetTileOwner(tile, new_player); |
1102 |
1071 } else { |
1103 if (GetRoadOwner(tile, rt) == old_player) { |
1072 switch (GetRoadTileType(tile)) { |
1104 SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player); |
1073 case ROAD_TILE_NORMAL: |
1105 |
1074 SetTileOwner(tile, OWNER_NONE); |
1106 if (rt == ROADTYPE_TRAM) { |
1075 break; |
1107 DoCommand(tile, ROADTYPE_TRAM << 4 | GetRoadBits(tile, ROADTYPE_ROAD), 0, DC_EXEC, CMD_REMOVE_ROAD); |
1076 |
1108 } |
1077 case ROAD_TILE_CROSSING: |
1109 } |
1078 MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile)); |
1110 } |
1079 break; |
1111 |
1080 |
1112 if (IsLevelCrossing(tile)) { |
1081 default: |
1113 MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); |
1082 case ROAD_TILE_DEPOT: |
|
1083 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
|
1084 break; |
|
1085 } |
|
1086 } |
1114 } |
1087 } |
1115 } |
1088 |
1116 |
1089 |
1117 |
1090 extern const TileTypeProcs _tile_type_road_procs = { |
1118 extern const TileTypeProcs _tile_type_road_procs = { |