195 * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge. |
195 * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge. |
196 */ |
196 */ |
197 int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
197 int32 CmdBuildBridge(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
198 { |
198 { |
199 int bridge_type; |
199 int bridge_type; |
200 byte m5; |
|
201 TransportType transport; |
200 TransportType transport; |
202 RailType railtype; |
201 RailType railtype; |
203 int sx,sy; |
202 int sx,sy; |
204 TileInfo ti_start, ti_end; |
203 TileInfo ti_start, ti_end; |
205 TileIndex tile; |
204 TileIndex tile; |
332 odd_middle_part = (bridge_len % 2) ? (bridge_len / 2) : bridge_len; |
331 odd_middle_part = (bridge_len % 2) ? (bridge_len / 2) : bridge_len; |
333 |
332 |
334 tile = ti_start.tile; |
333 tile = ti_start.tile; |
335 delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); |
334 delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); |
336 for (i = 0; i != bridge_len; i++) { |
335 for (i = 0; i != bridge_len; i++) { |
|
336 TransportType transport_under; |
337 uint z; |
337 uint z; |
338 |
338 |
339 tile += delta; |
339 tile += delta; |
340 |
340 |
341 if (GetTileSlope(tile, &z) != 0 && z >= ti_start.z) { |
341 if (GetTileSlope(tile, &z) != 0 && z >= ti_start.z) { |
344 |
344 |
345 switch (GetTileType(tile)) { |
345 switch (GetTileType(tile)) { |
346 case MP_WATER: |
346 case MP_WATER: |
347 if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY); |
347 if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY); |
348 if (_m[tile].m5 > 1) goto not_valid_below; |
348 if (_m[tile].m5 > 1) goto not_valid_below; |
349 m5 = 0xC8; |
349 transport_under = TRANSPORT_WATER; |
350 break; |
350 break; |
351 |
351 |
352 case MP_RAILWAY: |
352 case MP_RAILWAY: |
353 if (_m[tile].m5 != (direction == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X)) { |
353 if (_m[tile].m5 != (direction == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X)) { |
354 goto not_valid_below; |
354 goto not_valid_below; |
355 } |
355 } |
356 m5 = 0xE0; |
356 transport_under = TRANSPORT_RAIL; |
357 break; |
357 break; |
358 |
358 |
359 case MP_STREET: |
359 case MP_STREET: |
360 if (GetRoadType(tile) != ROAD_NORMAL || |
360 if (GetRoadType(tile) != ROAD_NORMAL || |
361 GetRoadBits(tile) != (direction == AXIS_X ? ROAD_Y : ROAD_X)) { |
361 GetRoadBits(tile) != (direction == AXIS_X ? ROAD_Y : ROAD_X)) { |
362 goto not_valid_below; |
362 goto not_valid_below; |
363 } |
363 } |
364 m5 = 0xE8; |
364 transport_under = TRANSPORT_ROAD; |
365 break; |
365 break; |
366 |
366 |
367 default: |
367 default: |
368 not_valid_below:; |
368 not_valid_below:; |
369 /* try and clear the middle landscape */ |
369 /* try and clear the middle landscape */ |
370 ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
370 ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
371 if (CmdFailed(ret)) return ret; |
371 if (CmdFailed(ret)) return ret; |
372 cost += ret; |
372 cost += ret; |
373 m5 = 0xC0; |
373 transport_under = INVALID_TRANSPORT; |
374 break; |
374 break; |
375 } |
375 } |
376 |
376 |
377 /* do middle part of bridge */ |
377 /* do middle part of bridge */ |
378 if (flags & DC_EXEC) { |
378 if (flags & DC_EXEC) { |
379 _m[tile].m5 = (byte)(m5 | direction | transport << 1); |
379 uint piece; |
|
380 |
380 SetTileType(tile, MP_TUNNELBRIDGE); |
381 SetTileType(tile, MP_TUNNELBRIDGE); |
381 |
382 |
382 //bridges pieces sequence (middle parts) |
383 //bridges pieces sequence (middle parts) |
383 // bridge len 1: 0 |
384 // bridge len 1: 0 |
384 // bridge len 2: 0 1 |
385 // bridge len 2: 0 1 |
390 // #0 - always as first, #1 - always as last (if len>1) |
391 // #0 - always as first, #1 - always as last (if len>1) |
391 // #2,#3 are to pair in order |
392 // #2,#3 are to pair in order |
392 // for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0) |
393 // for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0) |
393 |
394 |
394 if (i == 0) { // first tile |
395 if (i == 0) { // first tile |
395 m5 = 0; |
396 piece = 0; |
396 } else if (i == bridge_len - 1) { // last tile |
397 } else if (i == bridge_len - 1) { // last tile |
397 m5 = 1; |
398 piece = 1; |
398 } else if (i == odd_middle_part) { // we are on the middle of odd bridge: #5 on even pos, #4 on odd |
399 } else if (i == odd_middle_part) { // we are on the middle of odd bridge: #5 on even pos, #4 on odd |
399 m5 = 5 - (i % 2); |
400 piece = 5 - (i % 2); |
400 } else { |
401 } else { |
401 // generate #2 and #3 in turns [i%2==0], after the middle of odd bridge |
402 // generate #2 and #3 in turns [i%2==0], after the middle of odd bridge |
402 // this sequence swaps [... XOR (i>odd_middle_part)], |
403 // this sequence swaps [... XOR (i>odd_middle_part)], |
403 // for even bridges XOR does not apply as odd_middle_part==bridge_len |
404 // for even bridges XOR does not apply as odd_middle_part==bridge_len |
404 m5 = 2 + ((i % 2 == 0) ^ (i > odd_middle_part)); |
405 piece = 2 + ((i % 2 == 0) ^ (i > odd_middle_part)); |
405 } |
406 } |
406 |
407 |
407 _m[tile].m2 = (bridge_type << 4) | m5; |
408 _m[tile].m2 = (bridge_type << 4) | piece; |
408 SB(_m[tile].m3, 4, 4, railtype); |
409 SB(_m[tile].m3, 4, 4, railtype); |
|
410 switch (transport_under) { |
|
411 case TRANSPORT_RAIL: _m[tile].m5 = 0xE0 | TRANSPORT_RAIL << 3 | transport << 1 | direction; break; // rail |
|
412 case TRANSPORT_ROAD: _m[tile].m5 = 0xE0 | TRANSPORT_ROAD << 3 | transport << 1 | direction; break; // road |
|
413 case TRANSPORT_WATER: _m[tile].m5 = 0xC0 | 1 << 3 | transport << 1 | direction; break; // water |
|
414 default: _m[tile].m5 = 0xC0 | 0 << 3 | transport << 1 | direction; break; // grass |
|
415 } |
409 |
416 |
410 MarkTileDirtyByTile(tile); |
417 MarkTileDirtyByTile(tile); |
411 } |
418 } |
412 } |
419 } |
413 |
420 |