tunnelbridge_cmd.c
changeset 3188 c2eb40c2224b
parent 3187 0813719b05a9
child 3189 1af302c5abd0
equal deleted inserted replaced
3187:0813719b05a9 3188:c2eb40c2224b
   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