85 TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, -1)); |
85 TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, -1)); |
86 TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, 0)); |
86 TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, 0)); |
87 TerraformAddDirtyTile(ts, tile); |
87 TerraformAddDirtyTile(ts, tile); |
88 } |
88 } |
89 |
89 |
90 static int TerraformProc(TerraformerState *ts, TileIndex tile) |
90 static int TerraformProc(TerraformerState *ts, TileIndex tile, int mode) |
91 { |
91 { |
92 int r; |
92 int r; |
|
93 int32 ret; |
93 |
94 |
94 assert(tile < MapSize()); |
95 assert(tile < MapSize()); |
95 |
96 |
96 if ((r = TerraformAllowTileProcess(ts, tile)) <= 0) return r; |
97 if ((r=TerraformAllowTileProcess(ts, tile)) <= 0) |
97 |
98 return r; |
98 if (!IsTileType(tile, MP_RAILWAY)) { |
99 |
99 int32 ret = DoCommand(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR); |
100 if (IsTileType(tile, MP_RAILWAY)) { |
100 |
101 static const TrackBits _railway_modes[] = { TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER, TRACK_BIT_RIGHT }; |
101 if (CmdFailed(ret)) { |
102 static const byte _railway_dangslopes[4] = {0xd, 0xe, 7, 0xb}; |
|
103 static const byte _railway_dangslopes2[4] = {0x2, 0x1, 0x8, 0x4}; |
|
104 |
|
105 // Nothing could be built at the steep slope - this avoids a bug |
|
106 // when you have a single diagonal track in one corner on a |
|
107 // basement and then you raise/lower the other corner. |
|
108 int tileh = GetTileSlope(tile, NULL) & 0xF; |
|
109 if (tileh == _railway_dangslopes[mode] || |
|
110 tileh == _railway_dangslopes2[mode]) { |
102 _terraform_err_tile = tile; |
111 _terraform_err_tile = tile; |
|
112 _error_message = STR_1008_MUST_REMOVE_RAILROAD_TRACK; |
103 return -1; |
113 return -1; |
104 } |
114 } |
105 |
115 |
106 ts->cost += ret; |
116 // If we have a single diagonal track there, the other side of |
107 } |
117 // tile can be terraformed. |
|
118 if (IsPlainRailTile(tile) && GetTrackBits(tile) == _railway_modes[mode]) { |
|
119 return 0; |
|
120 } |
|
121 } |
|
122 |
|
123 ret = DoCommand(tile, 0,0, ts->flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR); |
|
124 |
|
125 if (ret == CMD_ERROR) { |
|
126 _terraform_err_tile = tile; |
|
127 return -1; |
|
128 } |
|
129 |
|
130 ts->cost += ret; |
108 |
131 |
109 if (ts->tile_table_count >= 625) return -1; |
132 if (ts->tile_table_count >= 625) return -1; |
110 ts->tile_table[ts->tile_table_count++] = tile; |
133 ts->tile_table[ts->tile_table_count++] = tile; |
111 |
134 |
112 return 0; |
135 return 0; |
130 if (height > 15) return false; |
153 if (height > 15) return false; |
131 |
154 |
132 nh = TerraformGetHeightOfTile(ts, tile); |
155 nh = TerraformGetHeightOfTile(ts, tile); |
133 if (nh < 0 || height == nh) return false; |
156 if (nh < 0 || height == nh) return false; |
134 |
157 |
135 if (TerraformProc(ts, tile) < 0) return false; |
158 if (TerraformProc(ts, tile, 0) < 0) return false; |
136 if (TerraformProc(ts, tile + TileDiffXY( 0, -1)) < 0) return false; |
159 if (TerraformProc(ts, tile + TileDiffXY( 0, -1), 1) < 0) return false; |
137 if (TerraformProc(ts, tile + TileDiffXY(-1, -1)) < 0) return false; |
160 if (TerraformProc(ts, tile + TileDiffXY(-1, -1), 2) < 0) return false; |
138 if (TerraformProc(ts, tile + TileDiffXY(-1, 0)) < 0) return false; |
161 if (TerraformProc(ts, tile + TileDiffXY(-1, 0), 3) < 0) return false; |
139 |
162 |
140 mod = ts->modheight; |
163 mod = ts->modheight; |
141 count = ts->modheight_count; |
164 count = ts->modheight_count; |
142 |
165 |
143 for (;;) { |
166 for (;;) { |
235 if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) { |
258 if (!TerraformTileHeight(&ts, t, TileHeight(t) + direction)) { |
236 return CMD_ERROR; |
259 return CMD_ERROR; |
237 } |
260 } |
238 } |
261 } |
239 |
262 |
240 { /* Check if tunnel or track would take damage */ |
263 if (direction == -1) { |
|
264 /* Check if tunnel would take damage */ |
241 int count; |
265 int count; |
242 TileIndex *ti = ts.tile_table; |
266 TileIndex *ti = ts.tile_table; |
243 |
267 |
244 for (count = ts.tile_table_count; count != 0; count--, ti++) { |
268 for (count = ts.tile_table_count; count != 0; count--, ti++) { |
245 uint a, b, c, d, min; |
269 uint z, t; |
246 Slope s; |
|
247 TileIndex tile = *ti; |
270 TileIndex tile = *ti; |
248 |
271 |
249 _terraform_err_tile = tile; |
272 z = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0)); |
250 |
273 t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0)); |
251 a = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 0)); |
274 if (t <= z) z = t; |
252 b = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 0)); |
275 t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1)); |
253 c = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1)); |
276 if (t <= z) z = t; |
254 d = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(1, 1)); |
277 t = TerraformGetHeightOfTile(&ts, tile + TileDiffXY(0, 1)); |
255 |
278 if (t <= z) z = t; |
256 s = GetTileh(a, b, c, d, &min); |
279 |
257 |
280 if (IsTunnelInWay(tile, z * TILE_HEIGHT)) { |
258 if (IsTileType(tile, MP_RAILWAY)) { |
281 return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE); |
259 if (IsSteepSlope(s)) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK); |
282 } |
260 |
|
261 if (IsPlainRailTile(tile)) { |
|
262 /* If a piece of rail is on a foundation, prohibit any terraforming |
|
263 * of that tile. We do need to check this with the original slope, not |
|
264 * the would-be one. */ |
|
265 extern const TrackBits _valid_tileh_slopes[2][15]; |
|
266 TrackBits tb = GetTrackBits(tile); |
|
267 |
|
268 if (GetRailFoundation(GetTileSlope(tile, NULL), tb) != 0) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK); |
|
269 if (tb & ~_valid_tileh_slopes[0][s]) return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK); |
|
270 } else return_cmd_error(STR_5800_OBJECT_IN_THE_WAY); |
|
271 } |
|
272 |
|
273 if (direction == -1 && IsTunnelInWay(tile, min)) return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE); |
|
274 |
|
275 _terraform_err_tile = 0; |
|
276 } |
283 } |
277 } |
284 } |
278 |
285 |
279 if (flags & DC_EXEC) { |
286 if (flags & DC_EXEC) { |
280 /* Clear the landscape at the tiles */ |
287 /* Clear the landscape at the tiles */ |