branch | NewGRF_ports |
changeset 6878 | 7d1ff2f621c7 |
parent 6877 | 889301acc299 |
child 10184 | fcf5fb2548eb |
6877:889301acc299 | 6878:7d1ff2f621c7 |
---|---|
31 #include "functions.h" |
31 #include "functions.h" |
32 #include "vehicle_func.h" |
32 #include "vehicle_func.h" |
33 #include "sound_func.h" |
33 #include "sound_func.h" |
34 #include "signal_func.h" |
34 #include "signal_func.h" |
35 #include "tunnelbridge.h" |
35 #include "tunnelbridge.h" |
36 #include "player_base.h" |
|
36 |
37 |
37 #include "table/sprites.h" |
38 #include "table/sprites.h" |
38 #include "table/strings.h" |
39 #include "table/strings.h" |
39 #include "table/bridge_land.h" |
40 #include "table/bridge_land.h" |
40 |
41 |
41 |
42 BridgeSpec _bridge[MAX_BRIDGES]; |
42 /** Describes the data that defines each bridge in the game |
43 |
43 * @param y year of availablity |
44 /** Reset the data been eventually changed by the grf loaded. */ |
44 * @param mnl minimum length |
45 void ResetBridges() |
45 * @param mxl maximum length |
46 { |
46 * @param p price |
47 /* First, free sprite table data */ |
47 * @param mxs maximum speed allowed |
48 for (BridgeType i = 0; i < MAX_BRIDGES; i++) { |
48 * @param spr sprite to use in purchase GUI |
49 if (_bridge[i].sprite_table != NULL) { |
49 * @param plt palette for the sprite in purchase GUI |
50 for (uint j = 0; j < 7; j++) free(_bridge[i].sprite_table[j]); |
50 * @param dsc description of the bridge in purchase GUI |
51 free(_bridge[i].sprite_table); |
51 * @param nrl description of the rail bridge in query tool |
52 } |
52 * @param nrd description of the road bridge in query tool |
53 } |
53 */ |
54 |
54 #define MB(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd) \ |
55 /* Then, wipe out current bidges */ |
55 {y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd, NULL, 0} |
56 memset(&_bridge, 0, sizeof(_bridge)); |
56 |
57 /* And finally, reinstall default data */ |
57 const Bridge orig_bridge[] = { |
58 memcpy(&_bridge, &_orig_bridge, sizeof(_orig_bridge)); |
58 /* |
59 } |
59 year of availablity |
|
60 | minimum length |
|
61 | | maximum length |
|
62 | | | price |
|
63 | | | | maximum speed |
|
64 | | | | | sprite to use in GUI |
|
65 | | | | | | palette in GUI |
|
66 string with description name on rail name on road |
|
67 | | | */ |
|
68 MB( 0, 0, 16, 80, 32, 0xA24, PAL_NONE, |
|
69 STR_5012_WOODEN, STR_501F_WOODEN_RAIL_BRIDGE, STR_5025_WOODEN_ROAD_BRIDGE), |
|
70 |
|
71 MB( 0, 0, 2, 112, 48, 0xA26, PALETTE_TO_STRUCT_RED, |
|
72 STR_5013_CONCRETE, STR_5020_CONCRETE_RAIL_BRIDGE, STR_5026_CONCRETE_ROAD_BRIDGE), |
|
73 |
|
74 MB( 1930, 0, 5, 144, 64, 0xA25, PAL_NONE, |
|
75 STR_500F_GIRDER_STEEL, STR_501C_STEEL_GIRDER_RAIL_BRIDGE, STR_5022_STEEL_GIRDER_ROAD_BRIDGE), |
|
76 |
|
77 MB( 0, 2, 10, 168, 80, 0xA22, PALETTE_TO_STRUCT_CONCRETE, |
|
78 STR_5011_SUSPENSION_CONCRETE, STR_501E_REINFORCED_CONCRETE_SUSPENSION, STR_5024_REINFORCED_CONCRETE_SUSPENSION), |
|
79 |
|
80 MB( 1930, 3, 16, 185, 96, 0xA22, PAL_NONE, |
|
81 STR_500E_SUSPENSION_STEEL, STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE, STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE), |
|
82 |
|
83 MB( 1930, 3, 16, 192, 112, 0xA22, PALETTE_TO_STRUCT_YELLOW, |
|
84 STR_500E_SUSPENSION_STEEL, STR_501B_STEEL_SUSPENSION_RAIL_BRIDGE, STR_5021_STEEL_SUSPENSION_ROAD_BRIDGE), |
|
85 |
|
86 MB( 1930, 3, 7, 224, 160, 0xA23, PAL_NONE, |
|
87 STR_5010_CANTILEVER_STEEL, STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE, STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE), |
|
88 |
|
89 MB( 1930, 3, 8, 232, 208, 0xA23, PALETTE_TO_STRUCT_BROWN, |
|
90 STR_5010_CANTILEVER_STEEL, STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE, STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE), |
|
91 |
|
92 MB( 1930, 3, 9, 248, 240, 0xA23, PALETTE_TO_STRUCT_RED, |
|
93 STR_5010_CANTILEVER_STEEL, STR_501D_STEEL_CANTILEVER_RAIL_BRIDGE, STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE), |
|
94 |
|
95 MB( 1930, 0, 2, 240, 256, 0xA27, PAL_NONE, |
|
96 STR_500F_GIRDER_STEEL, STR_501C_STEEL_GIRDER_RAIL_BRIDGE, STR_5022_STEEL_GIRDER_ROAD_BRIDGE), |
|
97 |
|
98 MB( 1995, 2, 16, 255, 320, 0xA28, PAL_NONE, |
|
99 STR_5014_TUBULAR_STEEL, STR_5027_TUBULAR_RAIL_BRIDGE, STR_5028_TUBULAR_ROAD_BRIDGE), |
|
100 |
|
101 MB( 2005, 2, 32, 380, 512, 0xA28, PALETTE_TO_STRUCT_YELLOW, |
|
102 STR_5014_TUBULAR_STEEL, STR_5027_TUBULAR_RAIL_BRIDGE, STR_5028_TUBULAR_ROAD_BRIDGE), |
|
103 |
|
104 MB( 2010, 2, 32, 510, 608, 0xA28, PALETTE_TO_STRUCT_GREY, |
|
105 STR_BRIDGE_TUBULAR_SILICON, STR_5027_TUBULAR_RAIL_BRIDGE, STR_5028_TUBULAR_ROAD_BRIDGE) |
|
106 }; |
|
107 |
|
108 #undef MB |
|
109 |
|
110 Bridge _bridge[MAX_BRIDGES]; |
|
111 |
|
112 |
60 |
113 /** calculate the price factor for building a long bridge. |
61 /** calculate the price factor for building a long bridge. |
114 * basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6, 7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8, |
62 * basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6, 7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8, |
115 */ |
63 */ |
116 int CalcBridgeLenCostFactor(int x) |
64 int CalcBridgeLenCostFactor(int x) |
150 return (tileh != SLOPE_FLAT); |
98 return (tileh != SLOPE_FLAT); |
151 } |
99 } |
152 |
100 |
153 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
101 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
154 { |
102 { |
155 const Bridge *bridge = &_bridge[index]; |
103 const BridgeSpec *bridge = GetBridgeSpec(index); |
156 assert(table < 7); |
104 assert(table < 7); |
157 if (bridge->sprite_table == NULL || bridge->sprite_table[table] == NULL) { |
105 if (bridge->sprite_table == NULL || bridge->sprite_table[table] == NULL) { |
158 return _bridge_sprite_table[index][table]; |
106 return _bridge_sprite_table[index][table]; |
159 } else { |
107 } else { |
160 return bridge->sprite_table[table]; |
108 return bridge->sprite_table[table]; |
161 } |
109 } |
162 } |
110 } |
163 |
|
164 static inline byte GetBridgeFlags(int index) { return _bridge[index].flags;} |
|
165 |
111 |
166 |
112 |
167 /** |
113 /** |
168 * Determines the foundation for the north bridge head, and tests if the resulting slope is valid. |
114 * Determines the foundation for the north bridge head, and tests if the resulting slope is valid. |
169 * |
115 * |
204 if (f == FOUNDATION_NONE) return CommandCost(); |
150 if (f == FOUNDATION_NONE) return CommandCost(); |
205 |
151 |
206 return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform); |
152 return CommandCost(EXPENSES_CONSTRUCTION, _price.terraform); |
207 } |
153 } |
208 |
154 |
209 bool CheckBridge_Stuff(byte bridge_type, uint bridge_len) |
155 bool CheckBridge_Stuff(BridgeType bridge_type, uint bridge_len) |
210 { |
156 { |
211 const Bridge *b = &_bridge[bridge_type]; |
157 const BridgeSpec *b = GetBridgeSpec(bridge_type); |
212 uint max; // max possible length of a bridge (with patch 100) |
158 uint max; // max possible length of a bridge (with patch 100) |
213 |
159 |
214 if (bridge_type >= MAX_BRIDGES) return false; |
160 if (bridge_type >= MAX_BRIDGES) return false; |
215 if (b->avail_year > _cur_year) return false; |
161 if (b->avail_year > _cur_year) return false; |
216 |
162 |
229 * - p2 = (bit 8-..) - rail type or road types. |
175 * - p2 = (bit 8-..) - rail type or road types. |
230 * - p2 = (bit 15 ) - set means road bridge. |
176 * - p2 = (bit 15 ) - set means road bridge. |
231 */ |
177 */ |
232 CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
178 CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2) |
233 { |
179 { |
234 uint bridge_type; |
180 BridgeType bridge_type; |
235 RailType railtype; |
181 RailType railtype = INVALID_RAILTYPE; |
236 RoadTypes roadtypes; |
182 RoadTypes roadtypes = ROADTYPES_NONE; |
237 uint x; |
183 uint x; |
238 uint y; |
184 uint y; |
239 uint sx; |
185 uint sx; |
240 uint sy; |
186 uint sy; |
241 TileIndex tile_start; |
187 TileIndex tile_start; |
249 uint bridge_len; |
195 uint bridge_len; |
250 Axis direction; |
196 Axis direction; |
251 CommandCost cost(EXPENSES_CONSTRUCTION); |
197 CommandCost cost(EXPENSES_CONSTRUCTION); |
252 CommandCost ret; |
198 CommandCost ret; |
253 bool replace_bridge = false; |
199 bool replace_bridge = false; |
254 uint replaced_bridge_type; |
200 BridgeType replaced_bridge_type; |
201 TransportType transport_type; |
|
255 |
202 |
256 /* unpack parameters */ |
203 /* unpack parameters */ |
257 bridge_type = GB(p2, 0, 8); |
204 bridge_type = GB(p2, 0, 8); |
258 |
205 |
259 if (p1 >= MapSize()) return CMD_ERROR; |
206 if (p1 >= MapSize()) return CMD_ERROR; |
260 |
207 |
208 transport_type = (TransportType)GB(p2, 15, 2); |
|
209 |
|
261 /* type of bridge */ |
210 /* type of bridge */ |
262 if (HasBit(p2, 15)) { |
211 switch (transport_type) { |
263 railtype = INVALID_RAILTYPE; // road bridge |
212 case TRANSPORT_ROAD: |
264 roadtypes = (RoadTypes)GB(p2, 8, 3); |
213 roadtypes = (RoadTypes)GB(p2, 8, 3); |
265 if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_player, roadtypes)) return CMD_ERROR; |
214 if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_player, roadtypes)) return CMD_ERROR; |
266 } else { |
215 break; |
267 if (!ValParamRailtype((RailType)GB(p2, 8, 8))) return CMD_ERROR; |
216 |
268 railtype = (RailType)GB(p2, 8, 8); |
217 case TRANSPORT_RAIL: |
269 roadtypes = ROADTYPES_NONE; |
218 railtype = (RailType)GB(p2, 8, 8); |
219 if (!ValParamRailtype(railtype)) return CMD_ERROR; |
|
220 break; |
|
221 |
|
222 default: |
|
223 /* For now, only TRANSPORT_RAIL and TRANSPORT_ROAD are allowed. |
|
224 * But let not this stops us for preparing the future */ |
|
225 return CMD_ERROR; |
|
270 } |
226 } |
271 |
227 |
272 x = TileX(end_tile); |
228 x = TileX(end_tile); |
273 y = TileY(end_tile); |
229 y = TileY(end_tile); |
274 sx = TileX(p1); |
230 sx = TileX(p1); |
299 |
255 |
300 tileh_start = GetTileSlope(tile_start, &z_start); |
256 tileh_start = GetTileSlope(tile_start, &z_start); |
301 tileh_end = GetTileSlope(tile_end, &z_end); |
257 tileh_end = GetTileSlope(tile_end, &z_end); |
302 |
258 |
303 CommandCost terraform_cost_north = CheckBridgeSlopeNorth(direction, &tileh_start, &z_start); |
259 CommandCost terraform_cost_north = CheckBridgeSlopeNorth(direction, &tileh_start, &z_start); |
304 CommandCost terraform_cost_south = CheckBridgeSlopeSouth(direction, &tileh_end, &z_end); |
260 CommandCost terraform_cost_south = CheckBridgeSlopeSouth(direction, &tileh_end, &z_end); |
305 |
261 |
306 if (z_start != z_end) return_cmd_error(STR_BRIDGEHEADS_NOT_SAME_HEIGHT); |
262 if (z_start != z_end) return_cmd_error(STR_BRIDGEHEADS_NOT_SAME_HEIGHT); |
307 |
|
308 TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL; |
|
309 |
263 |
310 if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) && |
264 if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) && |
311 GetOtherBridgeEnd(tile_start) == tile_end && |
265 GetOtherBridgeEnd(tile_start) == tile_end && |
312 GetTunnelBridgeTransportType(tile_start) == transport_type) { |
266 GetTunnelBridgeTransportType(tile_start) == transport_type) { |
313 /* Replace a current bridge. */ |
267 /* Replace a current bridge. */ |
317 return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
271 return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
318 } |
272 } |
319 |
273 |
320 /* Do not replace town bridges with lower speed bridges. */ |
274 /* Do not replace town bridges with lower speed bridges. */ |
321 if (!(flags & DC_QUERY_COST) && IsTileOwner(tile_start, OWNER_TOWN) && |
275 if (!(flags & DC_QUERY_COST) && IsTileOwner(tile_start, OWNER_TOWN) && |
322 _bridge[bridge_type].speed < _bridge[GetBridgeType(tile_start)].speed) { |
276 GetBridgeSpec(bridge_type)->speed < GetBridgeSpec(GetBridgeType(tile_start))->speed) { |
323 Town *t = ClosestTownFromTile(tile_start, UINT_MAX); |
277 Town *t = ClosestTownFromTile(tile_start, UINT_MAX); |
324 |
278 |
325 if (t == NULL) { |
279 if (t == NULL) { |
326 return CMD_ERROR; |
280 return CMD_ERROR; |
327 } else { |
281 } else { |
393 /* do the drill? */ |
347 /* do the drill? */ |
394 if (flags & DC_EXEC) { |
348 if (flags & DC_EXEC) { |
395 DiagDirection dir = AxisToDiagDir(direction); |
349 DiagDirection dir = AxisToDiagDir(direction); |
396 Owner owner = (replace_bridge && IsTileOwner(tile_start, OWNER_TOWN)) ? OWNER_TOWN : _current_player; |
350 Owner owner = (replace_bridge && IsTileOwner(tile_start, OWNER_TOWN)) ? OWNER_TOWN : _current_player; |
397 |
351 |
398 if (railtype != INVALID_RAILTYPE) { |
352 switch (transport_type) { |
399 MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); |
353 case TRANSPORT_RAIL: |
400 MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); |
354 MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); |
401 } else { |
355 MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); |
402 MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir, roadtypes); |
356 break; |
403 MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), roadtypes); |
357 |
358 case TRANSPORT_ROAD: |
|
359 MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir, roadtypes); |
|
360 MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), roadtypes); |
|
361 break; |
|
362 |
|
363 default: |
|
364 NOT_REACHED(); |
|
365 break; |
|
404 } |
366 } |
405 MarkTileDirtyByTile(tile_start); |
367 MarkTileDirtyByTile(tile_start); |
406 MarkTileDirtyByTile(tile_end); |
368 MarkTileDirtyByTile(tile_end); |
407 } |
369 } |
408 |
370 |
424 case MP_RAILWAY: |
386 case MP_RAILWAY: |
425 if (!IsPlainRailTile(tile)) goto not_valid_below; |
387 if (!IsPlainRailTile(tile)) goto not_valid_below; |
426 break; |
388 break; |
427 |
389 |
428 case MP_ROAD: |
390 case MP_ROAD: |
429 if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) goto not_valid_below; |
391 if (IsRoadDepot(tile)) goto not_valid_below; |
430 break; |
392 break; |
431 |
393 |
432 case MP_TUNNELBRIDGE: |
394 case MP_TUNNELBRIDGE: |
433 if (IsTunnel(tile)) break; |
395 if (IsTunnel(tile)) break; |
434 if (replace_bridge) break; |
396 if (replace_bridge) break; |
456 SetBridgeMiddle(tile, direction); |
418 SetBridgeMiddle(tile, direction); |
457 MarkTileDirtyByTile(tile); |
419 MarkTileDirtyByTile(tile); |
458 } |
420 } |
459 } |
421 } |
460 |
422 |
461 if (flags & DC_EXEC && railtype != INVALID_RAILTYPE) { |
423 if (flags & DC_EXEC && transport_type == TRANSPORT_RAIL) { |
462 Track track = AxisToTrack(direction); |
424 Track track = AxisToTrack(direction); |
463 AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_player); |
425 AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_player); |
464 YapfNotifyTrackLayoutChange(tile_start, track); |
426 YapfNotifyTrackLayoutChange(tile_start, track); |
465 } |
427 } |
466 |
428 |
467 /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST) |
429 /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST) |
468 * It's unnecessary to execute this command every time for every bridge. So it is done only |
430 * It's unnecessary to execute this command every time for every bridge. So it is done only |
469 * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated |
431 * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated |
470 */ |
432 */ |
471 if (!(flags & DC_QUERY_COST)) { |
433 if (!(flags & DC_QUERY_COST) || (IsValidPlayer(_current_player) && GetPlayer(_current_player)->is_ai)) { |
472 const Bridge *b = &_bridge[bridge_type]; |
|
473 |
|
474 bridge_len += 2; // begin and end tiles/ramps |
434 bridge_len += 2; // begin and end tiles/ramps |
475 |
435 |
476 if (IsValidPlayer(_current_player) && !_is_old_ai_player) |
436 if (IsValidPlayer(_current_player) && !_is_old_ai_player) |
477 bridge_len = CalcBridgeLenCostFactor(bridge_len); |
437 bridge_len = CalcBridgeLenCostFactor(bridge_len); |
478 |
438 |
479 cost.AddCost((int64)bridge_len * _price.build_bridge * b->price >> 8); |
439 cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8); |
480 } |
440 } |
481 |
441 |
482 return cost; |
442 return cost; |
483 } |
443 } |
484 |
444 |
494 TileIndexDiff delta; |
454 TileIndexDiff delta; |
495 TileIndex end_tile; |
455 TileIndex end_tile; |
496 DiagDirection direction; |
456 DiagDirection direction; |
497 Slope start_tileh; |
457 Slope start_tileh; |
498 Slope end_tileh; |
458 Slope end_tileh; |
459 TransportType transport_type = (TransportType)GB(p1, 9, 1); |
|
499 uint start_z; |
460 uint start_z; |
500 uint end_z; |
461 uint end_z; |
501 CommandCost cost(EXPENSES_CONSTRUCTION); |
462 CommandCost cost(EXPENSES_CONSTRUCTION); |
502 CommandCost ret; |
463 CommandCost ret; |
503 |
464 |
504 _build_tunnel_endtile = 0; |
465 _build_tunnel_endtile = 0; |
505 if (!HasBit(p1, 9)) { |
466 if (transport_type == TRANSPORT_RAIL) { |
506 if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; |
467 if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; |
507 } else { |
468 } else { |
508 const RoadTypes rts = (RoadTypes)GB(p1, 0, 3); |
469 const RoadTypes rts = (RoadTypes)GB(p1, 0, 3); |
509 if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR; |
470 if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR; |
510 } |
471 } |
583 } |
544 } |
584 cost.AddCost(_price.build_tunnel); |
545 cost.AddCost(_price.build_tunnel); |
585 cost.AddCost(ret); |
546 cost.AddCost(ret); |
586 |
547 |
587 if (flags & DC_EXEC) { |
548 if (flags & DC_EXEC) { |
588 if (GB(p1, 9, 1) == TRANSPORT_RAIL) { |
549 if (transport_type == TRANSPORT_RAIL) { |
589 MakeRailTunnel(start_tile, _current_player, direction, (RailType)GB(p1, 0, 4)); |
550 MakeRailTunnel(start_tile, _current_player, direction, (RailType)GB(p1, 0, 4)); |
590 MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4)); |
551 MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4)); |
591 AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_player); |
552 AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_player); |
592 YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction))); |
553 YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction))); |
593 } else { |
554 } else { |
649 |
610 |
650 DoClearSquare(tile); |
611 DoClearSquare(tile); |
651 DoClearSquare(endtile); |
612 DoClearSquare(endtile); |
652 |
613 |
653 /* cannot use INVALID_DIAGDIR for signal update because the tunnel doesn't exist anymore */ |
614 /* cannot use INVALID_DIAGDIR for signal update because the tunnel doesn't exist anymore */ |
654 AddSideToSignalBuffer(tile, ReverseDiagDir(dir), owner); |
615 AddSideToSignalBuffer(tile, ReverseDiagDir(dir), owner); |
655 AddSideToSignalBuffer(endtile, dir, owner); |
616 AddSideToSignalBuffer(endtile, dir, owner); |
656 |
617 |
657 Track track = AxisToTrack(DiagDirToAxis(dir)); |
618 Track track = AxisToTrack(DiagDirToAxis(dir)); |
658 YapfNotifyTrackLayoutChange(tile, track); |
619 YapfNotifyTrackLayoutChange(tile, track); |
659 YapfNotifyTrackLayoutChange(endtile, track); |
620 YapfNotifyTrackLayoutChange(endtile, track); |
660 } else { |
621 } else { |
661 DoClearSquare(tile); |
622 DoClearSquare(tile); |
662 DoClearSquare(endtile); |
623 DoClearSquare(endtile); |
663 } |
624 } |
701 |
662 |
702 if (flags & DC_EXEC) { |
663 if (flags & DC_EXEC) { |
703 /* read this value before actual removal of bridge */ |
664 /* read this value before actual removal of bridge */ |
704 bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL; |
665 bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL; |
705 Owner owner = GetTileOwner(tile); |
666 Owner owner = GetTileOwner(tile); |
667 uint height = GetBridgeHeight(tile); |
|
706 |
668 |
707 DoClearSquare(tile); |
669 DoClearSquare(tile); |
708 DoClearSquare(endtile); |
670 DoClearSquare(endtile); |
709 for (TileIndex c = tile + delta; c != endtile; c += delta) { |
671 for (TileIndex c = tile + delta; c != endtile; c += delta) { |
672 /* do not let trees appear from 'nowhere' after removing bridge */ |
|
673 if (IsNormalRoadTile(c) && GetRoadside(c) == ROADSIDE_TREES) { |
|
674 uint minz = GetTileMaxZ(c) + 3 * TILE_HEIGHT; |
|
675 if (height < minz) SetRoadside(c, ROADSIDE_PAVED); |
|
676 } |
|
710 ClearBridgeMiddle(c); |
677 ClearBridgeMiddle(c); |
711 MarkTileDirtyByTile(c); |
678 MarkTileDirtyByTile(c); |
712 } |
679 } |
713 |
680 |
714 if (rail) { |
681 if (rail) { |
715 /* cannot use INVALID_DIAGDIR for signal update because the bridge doesn't exist anymore */ |
682 /* cannot use INVALID_DIAGDIR for signal update because the bridge doesn't exist anymore */ |
716 AddSideToSignalBuffer(tile, ReverseDiagDir(direction), owner); |
683 AddSideToSignalBuffer(tile, ReverseDiagDir(direction), owner); |
717 AddSideToSignalBuffer(endtile, direction, owner); |
684 AddSideToSignalBuffer(endtile, direction, owner); |
718 |
685 |
719 Track track = AxisToTrack(DiagDirToAxis(direction)); |
686 Track track = AxisToTrack(DiagDirToAxis(direction)); |
720 YapfNotifyTrackLayoutChange(tile, track); |
687 YapfNotifyTrackLayoutChange(tile, track); |
721 YapfNotifyTrackLayoutChange(endtile, track); |
688 YapfNotifyTrackLayoutChange(endtile, track); |
722 } |
689 } |
723 } |
690 } |
724 |
691 |
725 return CommandCost(EXPENSES_CONSTRUCTION, (GetTunnelBridgeLength(tile, endtile) + 2) * _price.clear_bridge); |
692 return CommandCost(EXPENSES_CONSTRUCTION, (GetTunnelBridgeLength(tile, endtile) + 2) * _price.clear_bridge); |
747 * @param type Bridge type. |
714 * @param type Bridge type. |
748 * @param x Sprite X position of front pillar. |
715 * @param x Sprite X position of front pillar. |
749 * @param y Sprite Y position of front pillar. |
716 * @param y Sprite Y position of front pillar. |
750 * @param z_bridge Absolute height of bridge bottom. |
717 * @param z_bridge Absolute height of bridge bottom. |
751 */ |
718 */ |
752 static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, uint type, int x, int y, int z_bridge) |
719 static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, BridgeType type, int x, int y, int z_bridge) |
753 { |
720 { |
754 SpriteID image = psid->sprite; |
721 SpriteID image = psid->sprite; |
755 if (image != 0) { |
722 if (image != 0) { |
756 bool drawfarpillar = !HasBit(GetBridgeFlags(type), 0); |
723 bool drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0); |
757 |
724 |
758 /* "side" specifies the side the pillars stand on. |
725 /* "side" specifies the side the pillars stand on. |
759 * The length of the pillars is then set to the height of the bridge over the corners of this edge. |
726 * The length of the pillars is then set to the height of the bridge over the corners of this edge. |
760 * |
727 * |
761 * axis==AXIS_X axis==AXIS_Y |
728 * axis==AXIS_X axis==AXIS_Y |
817 |
784 |
818 /* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called |
785 /* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called |
819 * The bounding boxes here are the same as for bridge front/roof */ |
786 * The bounding boxes here are the same as for bridge front/roof */ |
820 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_BRIDGES)); |
787 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_BRIDGES)); |
821 |
788 |
822 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + back_offsets[offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_BUILDINGS)); |
789 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + back_offsets[offset], PAL_NONE, x, y, size_x[offset], size_y[offset], 0x28, z, IsTransparencySet(TO_CATENARY)); |
823 |
790 |
824 /* Start a new SpriteCombine for the front part */ |
791 /* Start a new SpriteCombine for the front part */ |
825 EndSpriteCombine(); |
792 EndSpriteCombine(); |
826 StartSpriteCombine(); |
793 StartSpriteCombine(); |
827 |
794 |
828 /* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */ |
795 /* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */ |
829 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + front_offsets[offset], PAL_NONE, x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z, IsTransparencySet(TO_BUILDINGS), front_bb_offset_x[offset], front_bb_offset_y[offset]); |
796 AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + front_offsets[offset], PAL_NONE, x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z, IsTransparencySet(TO_CATENARY), front_bb_offset_x[offset], front_bb_offset_y[offset]); |
830 } |
797 } |
831 |
798 |
832 /** |
799 /** |
833 * Draws a tunnel of bridge tile. |
800 * Draws a tunnel of bridge tile. |
834 * For tunnels, this is rather simple, as you only needa draw the entrance. |
801 * For tunnels, this is rather simple, as you only needa draw the entrance. |
843 * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 |
810 * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 |
844 */ |
811 */ |
845 static void DrawTile_TunnelBridge(TileInfo *ti) |
812 static void DrawTile_TunnelBridge(TileInfo *ti) |
846 { |
813 { |
847 SpriteID image; |
814 SpriteID image; |
815 TransportType transport_type = GetTunnelBridgeTransportType(ti->tile); |
|
816 DiagDirection tunnelbridge_direction = GetTunnelBridgeDirection(ti->tile); |
|
848 |
817 |
849 if (IsTunnel(ti->tile)) { |
818 if (IsTunnel(ti->tile)) { |
850 /* Front view of tunnel bounding boxes: |
819 /* Front view of tunnel bounding boxes: |
851 * |
820 * |
852 * 122223 <- BB_Z_SEPARATOR |
821 * 122223 <- BB_Z_SEPARATOR |
862 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // NE |
831 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // NE |
863 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // SE |
832 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // SE |
864 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // SW |
833 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 }, // SW |
865 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // NW |
834 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 }, // NW |
866 }; |
835 }; |
867 const int *BB_data = _tunnel_BB[GetTunnelBridgeDirection(ti->tile)]; |
836 const int *BB_data = _tunnel_BB[tunnelbridge_direction]; |
868 |
837 |
869 bool catenary = false; |
838 bool catenary = false; |
870 |
839 |
871 if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { |
840 if (transport_type == TRANSPORT_RAIL) { |
872 image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; |
841 image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; |
873 } else { |
842 } else { |
874 image = SPR_TUNNEL_ENTRY_REAR_ROAD; |
843 image = SPR_TUNNEL_ENTRY_REAR_ROAD; |
875 } |
844 } |
876 |
845 |
877 if (HasTunnelBridgeSnowOrDesert(ti->tile)) image += 32; |
846 if (HasTunnelBridgeSnowOrDesert(ti->tile)) image += 32; |
878 |
847 |
879 image += GetTunnelBridgeDirection(ti->tile) * 2; |
848 image += tunnelbridge_direction * 2; |
880 DrawGroundSprite(image, PAL_NONE); |
849 DrawGroundSprite(image, PAL_NONE); |
881 if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) { |
850 if (transport_type == TRANSPORT_ROAD) { |
882 DiagDirection dir = GetTunnelBridgeDirection(ti->tile); |
|
883 RoadTypes rts = GetRoadTypes(ti->tile); |
851 RoadTypes rts = GetRoadTypes(ti->tile); |
884 |
852 |
885 if (HasBit(rts, ROADTYPE_TRAM)) { |
853 if (HasBit(rts, ROADTYPE_TRAM)) { |
886 static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } }; |
854 static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } }; |
887 |
855 |
888 DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][dir], PAL_NONE); |
856 DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][tunnelbridge_direction], PAL_NONE); |
889 |
857 |
890 catenary = true; |
858 catenary = true; |
891 StartSpriteCombine(); |
859 StartSpriteCombine(); |
892 AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + dir, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_BUILDINGS), BB_data[8], BB_data[9], BB_Z_SEPARATOR); |
860 AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR); |
893 } |
861 } |
894 } else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) { |
862 } else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) { |
895 DrawCatenary(ti); |
863 DrawCatenary(ti); |
896 |
864 |
897 catenary = true; |
865 catenary = true; |
911 } else { // IsBridge(ti->tile) |
879 } else { // IsBridge(ti->tile) |
912 const PalSpriteID *psid; |
880 const PalSpriteID *psid; |
913 int base_offset; |
881 int base_offset; |
914 bool ice = HasTunnelBridgeSnowOrDesert(ti->tile); |
882 bool ice = HasTunnelBridgeSnowOrDesert(ti->tile); |
915 |
883 |
916 if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { |
884 if (transport_type == TRANSPORT_RAIL) { |
917 base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; |
885 base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; |
918 assert(base_offset != 8); // This one is used for roads |
886 assert(base_offset != 8); // This one is used for roads |
919 } else { |
887 } else { |
920 base_offset = 8; |
888 base_offset = 8; |
921 } |
889 } |
922 |
890 |
923 /* as the lower 3 bits are used for other stuff, make sure they are clear */ |
891 /* as the lower 3 bits are used for other stuff, make sure they are clear */ |
924 assert( (base_offset & 0x07) == 0x00); |
892 assert( (base_offset & 0x07) == 0x00); |
925 |
893 |
926 DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetTunnelBridgeDirection(ti->tile)))); |
894 DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction))); |
927 |
895 |
928 /* HACK Wizardry to convert the bridge ramp direction into a sprite offset */ |
896 /* HACK Wizardry to convert the bridge ramp direction into a sprite offset */ |
929 base_offset += (6 - GetTunnelBridgeDirection(ti->tile)) % 4; |
897 base_offset += (6 - tunnelbridge_direction) % 4; |
930 |
898 |
931 if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head |
899 if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head |
932 |
900 |
933 /* Table number 6 always refers to the bridge heads for any bridge type */ |
901 /* Table number 6 always refers to the bridge heads for any bridge type */ |
934 psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; |
902 psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; |
940 } |
908 } |
941 |
909 |
942 /* draw ramp */ |
910 /* draw ramp */ |
943 |
911 |
944 /* Draw Trambits as SpriteCombine */ |
912 /* Draw Trambits as SpriteCombine */ |
945 if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) StartSpriteCombine(); |
913 if (transport_type == TRANSPORT_ROAD) StartSpriteCombine(); |
946 |
914 |
947 /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on |
915 /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on |
948 * it doesn't disappear behind it |
916 * it doesn't disappear behind it |
949 */ |
917 */ |
950 AddSortableSpriteToDraw( |
918 AddSortableSpriteToDraw( |
951 psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z, IsTransparencySet(TO_BRIDGES) |
919 psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z, IsTransparencySet(TO_BRIDGES) |
952 ); |
920 ); |
953 |
921 |
954 if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) { |
922 if (transport_type == TRANSPORT_ROAD) { |
955 RoadTypes rts = GetRoadTypes(ti->tile); |
923 RoadTypes rts = GetRoadTypes(ti->tile); |
956 |
924 |
957 if (HasBit(rts, ROADTYPE_TRAM)) { |
925 if (HasBit(rts, ROADTYPE_TRAM)) { |
958 uint offset = GetTunnelBridgeDirection(ti->tile); |
926 uint offset = tunnelbridge_direction; |
959 uint z = ti->z; |
927 uint z = ti->z; |
960 if (ti->tileh != SLOPE_FLAT) { |
928 if (ti->tileh != SLOPE_FLAT) { |
961 offset = (offset + 1) & 1; |
929 offset = (offset + 1) & 1; |
962 z += TILE_HEIGHT; |
930 z += TILE_HEIGHT; |
963 } else { |
931 } else { |
1031 |
999 |
1032 const PalSpriteID* psid; |
1000 const PalSpriteID* psid; |
1033 uint base_offset; |
1001 uint base_offset; |
1034 TileIndex rampnorth; |
1002 TileIndex rampnorth; |
1035 TileIndex rampsouth; |
1003 TileIndex rampsouth; |
1004 TransportType transport_type; |
|
1036 Axis axis; |
1005 Axis axis; |
1037 uint piece; |
1006 uint piece; |
1038 uint type; |
1007 BridgeType type; |
1039 int x; |
1008 int x; |
1040 int y; |
1009 int y; |
1041 uint z; |
1010 uint z; |
1042 |
1011 |
1043 if (!IsBridgeAbove(ti->tile)) return; |
1012 if (!IsBridgeAbove(ti->tile)) return; |
1044 |
1013 |
1045 rampnorth = GetNorthernBridgeEnd(ti->tile); |
1014 rampnorth = GetNorthernBridgeEnd(ti->tile); |
1046 rampsouth = GetSouthernBridgeEnd(ti->tile); |
1015 rampsouth = GetSouthernBridgeEnd(ti->tile); |
1016 transport_type = GetTunnelBridgeTransportType(rampsouth); |
|
1047 |
1017 |
1048 axis = GetBridgeAxis(ti->tile); |
1018 axis = GetBridgeAxis(ti->tile); |
1049 piece = CalcBridgePiece( |
1019 piece = CalcBridgePiece( |
1050 GetTunnelBridgeLength(ti->tile, rampnorth) + 1, |
1020 GetTunnelBridgeLength(ti->tile, rampnorth) + 1, |
1051 GetTunnelBridgeLength(ti->tile, rampsouth) + 1 |
1021 GetTunnelBridgeLength(ti->tile, rampsouth) + 1 |
1052 ); |
1022 ); |
1053 type = GetBridgeType(rampsouth); |
1023 type = GetBridgeType(rampsouth); |
1054 |
1024 |
1055 if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_RAIL) { |
1025 if (transport_type == TRANSPORT_RAIL) { |
1056 base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset; |
1026 base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset; |
1057 } else { |
1027 } else { |
1058 base_offset = 8; |
1028 base_offset = 8; |
1059 } |
1029 } |
1060 |
1030 |
1068 |
1038 |
1069 /* Add a bounding box, that separates the bridge from things below it. */ |
1039 /* Add a bounding box, that separates the bridge from things below it. */ |
1070 AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR); |
1040 AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR); |
1071 |
1041 |
1072 /* Draw Trambits as SpriteCombine */ |
1042 /* Draw Trambits as SpriteCombine */ |
1073 if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) StartSpriteCombine(); |
1043 if (transport_type == TRANSPORT_ROAD) StartSpriteCombine(); |
1074 |
1044 |
1075 /* Draw floor and far part of bridge*/ |
1045 /* Draw floor and far part of bridge*/ |
1076 if (axis == AXIS_X) { |
1046 if (axis == AXIS_X) { |
1077 AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START); |
1047 AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START); |
1078 } else { |
1048 } else { |
1079 AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START); |
1049 AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START); |
1080 } |
1050 } |
1081 |
1051 |
1082 psid++; |
1052 psid++; |
1083 |
1053 |
1084 if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) { |
1054 if (transport_type == TRANSPORT_ROAD) { |
1085 RoadTypes rts = GetRoadTypes(rampsouth); |
1055 RoadTypes rts = GetRoadTypes(rampsouth); |
1086 |
1056 |
1087 if (HasBit(rts, ROADTYPE_TRAM)) { |
1057 if (HasBit(rts, ROADTYPE_TRAM)) { |
1088 /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */ |
1058 /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */ |
1089 DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD)); |
1059 DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD)); |
1103 x += 12; |
1073 x += 12; |
1104 if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START); |
1074 if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START); |
1105 } |
1075 } |
1106 |
1076 |
1107 /* Draw TramFront as SpriteCombine */ |
1077 /* Draw TramFront as SpriteCombine */ |
1108 if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) EndSpriteCombine(); |
1078 if (transport_type == TRANSPORT_ROAD) EndSpriteCombine(); |
1109 |
1079 |
1110 psid++; |
1080 psid++; |
1111 if (ti->z + 5 == z) { |
1081 if (ti->z + 5 == z) { |
1112 /* draw poles below for small bridges */ |
1082 /* draw poles below for small bridges */ |
1113 if (psid->sprite != 0) { |
1083 if (psid->sprite != 0) { |
1181 { |
1151 { |
1182 if (IsTunnel(tile)) { |
1152 if (IsTunnel(tile)) { |
1183 td->str = (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ? |
1153 td->str = (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ? |
1184 STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; |
1154 STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; |
1185 } else { //so it must be a bridge |
1155 } else { //so it must be a bridge |
1186 int brtype = GetBridgeType(tile); |
1156 td->str = GetBridgeSpec(GetBridgeType(tile))->transport_name[GetTunnelBridgeTransportType(tile)]; |
1187 td->str = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL ? _bridge[brtype].name_rail : _bridge[brtype].name_road; |
|
1188 } |
1157 } |
1189 td->owner = GetTileOwner(tile); |
1158 td->owner = GetTileOwner(tile); |
1190 } |
1159 } |
1191 |
1160 |
1192 |
1161 |
1222 { |
1191 { |
1223 /* not used */ |
1192 /* not used */ |
1224 } |
1193 } |
1225 |
1194 |
1226 |
1195 |
1227 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode) |
1196 static TrackStatus GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side) |
1228 { |
1197 { |
1229 if (GetTunnelBridgeTransportType(tile) != mode) return 0; |
1198 TransportType transport_type = GetTunnelBridgeTransportType(tile); |
1230 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0; |
1199 if (transport_type != mode || (transport_type == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0)) return 0; |
1231 return AxisToTrackBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) * 0x101; |
1200 |
1201 DiagDirection dir = GetTunnelBridgeDirection(tile); |
|
1202 if (side != INVALID_DIAGDIR && side != ReverseDiagDir(dir)) return 0; |
|
1203 return CombineTrackStatus(TrackBitsToTrackdirBits(AxisToTrackBits(DiagDirToAxis(dir))), TRACKDIR_BIT_NONE); |
|
1232 } |
1204 } |
1233 |
1205 |
1234 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1206 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1235 { |
1207 { |
1236 if (!IsTileOwner(tile, old_player)) return; |
1208 if (!IsTileOwner(tile, old_player)) return; |
1237 |
1209 |
1238 if (new_player != PLAYER_SPECTATOR) { |
1210 if (new_player != PLAYER_SPECTATOR) { |
1239 SetTileOwner(tile, new_player); |
1211 SetTileOwner(tile, new_player); |
1240 } else { |
1212 } else { |
1241 if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) { |
1213 if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR))) { |
1242 /* When clearing the bridge/tunnel failed there are still vehicles on/in |
1214 /* When clearing the bridge/tunnel failed there are still vehicles on/in |
1243 * the bridge/tunnel. As all *our* vehicles are already removed, they |
1215 * the bridge/tunnel. As all *our* vehicles are already removed, they |
1244 * must be of another owner. Therefor this must be a road bridge/tunnel. |
1216 * must be of another owner. Therefor this must be a road bridge/tunnel. |
1245 * In that case we can safely reassign the ownership to OWNER_NONE. */ |
1217 * In that case we can safely reassign the ownership to OWNER_NONE. */ |
1246 assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD); |
1218 assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD); |
1269 static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y) |
1241 static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y) |
1270 { |
1242 { |
1271 int z = GetSlopeZ(x, y) - v->z_pos; |
1243 int z = GetSlopeZ(x, y) - v->z_pos; |
1272 |
1244 |
1273 if (abs(z) > 2) return VETSB_CANNOT_ENTER; |
1245 if (abs(z) > 2) return VETSB_CANNOT_ENTER; |
1246 const DiagDirection dir = GetTunnelBridgeDirection(tile); |
|
1274 |
1247 |
1275 if (IsTunnel(tile)) { |
1248 if (IsTunnel(tile)) { |
1276 byte fc; |
1249 byte fc; |
1277 DiagDirection dir; |
|
1278 DiagDirection vdir; |
1250 DiagDirection vdir; |
1279 |
1251 |
1280 if (v->type == VEH_TRAIN) { |
1252 if (v->type == VEH_TRAIN) { |
1281 fc = (x & 0xF) + (y << 4); |
1253 fc = (x & 0xF) + (y << 4); |
1282 |
1254 |
1283 dir = GetTunnelBridgeDirection(tile); |
|
1284 vdir = DirToDiagDir(v->direction); |
1255 vdir = DirToDiagDir(v->direction); |
1285 |
1256 |
1286 if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) { |
1257 if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) { |
1287 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
1258 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
1288 if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) { |
1259 if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) { |
1306 v->vehstatus &= ~VS_HIDDEN; |
1277 v->vehstatus &= ~VS_HIDDEN; |
1307 return VETSB_ENTERED_WORMHOLE; |
1278 return VETSB_ENTERED_WORMHOLE; |
1308 } |
1279 } |
1309 } else if (v->type == VEH_ROAD) { |
1280 } else if (v->type == VEH_ROAD) { |
1310 fc = (x & 0xF) + (y << 4); |
1281 fc = (x & 0xF) + (y << 4); |
1311 dir = GetTunnelBridgeDirection(tile); |
|
1312 vdir = DirToDiagDir(v->direction); |
1282 vdir = DirToDiagDir(v->direction); |
1313 |
1283 |
1314 /* Enter tunnel? */ |
1284 /* Enter tunnel? */ |
1315 if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) { |
1285 if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) { |
1316 if (fc == _tunnel_fractcoord_4[dir] || |
1286 if (fc == _tunnel_fractcoord_4[dir] || |
1336 v->vehstatus &= ~VS_HIDDEN; |
1306 v->vehstatus &= ~VS_HIDDEN; |
1337 return VETSB_ENTERED_WORMHOLE; |
1307 return VETSB_ENTERED_WORMHOLE; |
1338 } |
1308 } |
1339 } |
1309 } |
1340 } else { // IsBridge(tile) |
1310 } else { // IsBridge(tile) |
1341 DiagDirection dir; |
|
1342 |
1311 |
1343 if (v->IsPrimaryVehicle()) { |
1312 if (v->IsPrimaryVehicle()) { |
1344 /* modify speed of vehicle */ |
1313 /* modify speed of vehicle */ |
1345 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
1314 uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed; |
1346 |
1315 |
1347 if (v->type == VEH_ROAD) spd *= 2; |
1316 if (v->type == VEH_ROAD) spd *= 2; |
1348 if (v->cur_speed > spd) v->cur_speed = spd; |
1317 if (v->cur_speed > spd) v->cur_speed = spd; |
1349 } |
1318 } |
1350 |
1319 |
1351 dir = GetTunnelBridgeDirection(tile); |
|
1352 if (DirToDiagDir(v->direction) == dir) { |
1320 if (DirToDiagDir(v->direction) == dir) { |
1353 switch (dir) { |
1321 switch (dir) { |
1354 default: NOT_REACHED(); |
1322 default: NOT_REACHED(); |
1355 case DIAGDIR_NE: if ((x & 0xF) != 0) return VETSB_CONTINUE; break; |
1323 case DIAGDIR_NE: if ((x & 0xF) != 0) return VETSB_CONTINUE; break; |
1356 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1324 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |