106 |
106 |
107 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) */ |
107 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) */ |
108 if (p1 >> 4) return CMD_ERROR; |
108 if (p1 >> 4) return CMD_ERROR; |
109 pieces = p1; |
109 pieces = p1; |
110 |
110 |
111 if (!IsTileType(tile, MP_STREET) && !IsTileType(tile, MP_TUNNELBRIDGE)) return CMD_ERROR; |
111 if (!IsTileType(tile, MP_STREET)) return CMD_ERROR; |
112 |
112 |
113 owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile); |
113 owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile); |
114 |
114 |
115 if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) { |
115 if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) { |
116 if (IsTileType(tile, MP_TUNNELBRIDGE)) { // index of town is not saved for bridge (no space) |
116 t = GetTownByTile(tile); |
117 t = ClosestTownFromTile(tile, _patches.dist_local_authority); |
|
118 } else { |
|
119 t = GetTownByTile(tile); |
|
120 } |
|
121 } else { |
117 } else { |
122 t = NULL; |
118 t = NULL; |
123 } |
119 } |
124 |
120 |
125 if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR; |
121 if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR; |
126 |
122 |
127 switch (GetTileType(tile)) { |
123 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
128 case MP_TUNNELBRIDGE: |
124 |
129 if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; |
125 // check if you're allowed to remove the street owned by a town |
130 |
126 // removal allowance depends on difficulty setting |
131 if (!IsBridge(tile) || |
127 if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; |
132 !IsBridgeMiddle(tile) || |
128 |
133 !IsTransportUnderBridge(tile) || |
129 switch (GetRoadTileType(tile)) { |
134 GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD || |
130 case ROAD_TILE_NORMAL: { |
135 (pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) { |
131 RoadBits present = GetRoadBits(tile); |
136 return CMD_ERROR; |
132 RoadBits c = pieces; |
137 } |
133 |
|
134 if (GetTileSlope(tile, NULL) != SLOPE_FLAT && |
|
135 (present == ROAD_Y || present == ROAD_X)) { |
|
136 c |= (c & 0xC) >> 2; |
|
137 c |= (c & 0x3) << 2; |
|
138 } |
|
139 |
|
140 // limit the bits to delete to the existing bits. |
|
141 c &= present; |
|
142 if (c == 0) return CMD_ERROR; |
138 |
143 |
139 if (flags & DC_EXEC) { |
144 if (flags & DC_EXEC) { |
140 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
145 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
141 SetClearUnderBridge(tile); |
146 |
|
147 present ^= c; |
|
148 if (present == 0) { |
|
149 DoClearSquare(tile); |
|
150 } else { |
|
151 SetRoadBits(tile, present); |
|
152 MarkTileDirtyByTile(tile); |
|
153 } |
|
154 } |
|
155 return CountRoadBits(c) * _price.remove_road; |
|
156 } |
|
157 |
|
158 case ROAD_TILE_CROSSING: { |
|
159 if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) { |
|
160 return CMD_ERROR; |
|
161 } |
|
162 |
|
163 if (flags & DC_EXEC) { |
|
164 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
|
165 |
|
166 MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile)); |
142 MarkTileDirtyByTile(tile); |
167 MarkTileDirtyByTile(tile); |
143 } |
168 } |
144 return _price.remove_road * 2; |
169 return _price.remove_road * 2; |
145 |
170 } |
146 case MP_STREET: |
171 |
147 if (!EnsureNoVehicle(tile)) return CMD_ERROR; |
172 case ROAD_TILE_DEPOT: |
148 |
173 default: |
149 // check if you're allowed to remove the street owned by a town |
174 return CMD_ERROR; |
150 // removal allowance depends on difficulty setting |
|
151 if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; |
|
152 |
|
153 switch (GetRoadTileType(tile)) { |
|
154 case ROAD_TILE_NORMAL: { |
|
155 RoadBits present = GetRoadBits(tile); |
|
156 RoadBits c = pieces; |
|
157 |
|
158 if (GetTileSlope(tile, NULL) != SLOPE_FLAT && |
|
159 (present == ROAD_Y || present == ROAD_X)) { |
|
160 c |= (c & 0xC) >> 2; |
|
161 c |= (c & 0x3) << 2; |
|
162 } |
|
163 |
|
164 // limit the bits to delete to the existing bits. |
|
165 c &= present; |
|
166 if (c == 0) return CMD_ERROR; |
|
167 |
|
168 if (flags & DC_EXEC) { |
|
169 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
|
170 |
|
171 present ^= c; |
|
172 if (present == 0) { |
|
173 DoClearSquare(tile); |
|
174 } else { |
|
175 SetRoadBits(tile, present); |
|
176 MarkTileDirtyByTile(tile); |
|
177 } |
|
178 } |
|
179 return CountRoadBits(c) * _price.remove_road; |
|
180 } |
|
181 |
|
182 case ROAD_TILE_CROSSING: { |
|
183 if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) { |
|
184 return CMD_ERROR; |
|
185 } |
|
186 |
|
187 if (flags & DC_EXEC) { |
|
188 ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); |
|
189 |
|
190 MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile)); |
|
191 MarkTileDirtyByTile(tile); |
|
192 } |
|
193 return _price.remove_road * 2; |
|
194 } |
|
195 |
|
196 default: |
|
197 case ROAD_TILE_DEPOT: |
|
198 return CMD_ERROR; |
|
199 } |
|
200 |
|
201 default: return CMD_ERROR; |
|
202 } |
175 } |
203 } |
176 } |
204 |
177 |
205 |
178 |
206 static const RoadBits _valid_tileh_slopes_road[][15] = { |
179 static const RoadBits _valid_tileh_slopes_road[][15] = { |
346 MarkTileDirtyByTile(tile); |
319 MarkTileDirtyByTile(tile); |
347 } |
320 } |
348 return _price.build_road * 2; |
321 return _price.build_road * 2; |
349 } |
322 } |
350 |
323 |
351 case MP_TUNNELBRIDGE: |
|
352 /* check for flat land */ |
|
353 if (IsSteepSlope(tileh)) { |
|
354 return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); |
|
355 } |
|
356 |
|
357 if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear; |
|
358 |
|
359 /* only allow roads pertendicular to bridge */ |
|
360 if ((pieces & (GetBridgeAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y)) != 0) { |
|
361 goto do_clear; |
|
362 } |
|
363 |
|
364 /* check if clear land under bridge */ |
|
365 if (IsTransportUnderBridge(tile)) { |
|
366 switch (GetTransportTypeUnderBridge(tile)) { |
|
367 case TRANSPORT_ROAD: return_cmd_error(STR_1007_ALREADY_BUILT); |
|
368 default: return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK); |
|
369 } |
|
370 } else { |
|
371 if (IsWaterUnderBridge(tile)) { |
|
372 return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); |
|
373 } |
|
374 } |
|
375 |
|
376 if (flags & DC_EXEC) { |
|
377 SetRoadUnderBridge(tile, _current_player); |
|
378 MarkTileDirtyByTile(tile); |
|
379 } |
|
380 return _price.build_road * 2; |
|
381 |
|
382 default: |
324 default: |
383 do_clear:; |
325 do_clear:; |
384 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
326 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
385 if (CmdFailed(ret)) return ret; |
327 if (CmdFailed(ret)) return ret; |
386 cost += ret; |
328 cost += ret; |