193 const int *BB_data = _tunnel_wire_BB[dir]; |
194 const int *BB_data = _tunnel_wire_BB[dir]; |
194 AddSortableSpriteToDraw( |
195 AddSortableSpriteToDraw( |
195 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
196 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
196 BB_data[2] - sss->x_offset, BB_data[3] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset + 1, |
197 BB_data[2] - sss->x_offset, BB_data[3] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset + 1, |
197 GetTileZ(ti->tile) + sss->z_offset, |
198 GetTileZ(ti->tile) + sss->z_offset, |
198 HASBIT(_transparent_opt, TO_BUILDINGS), |
199 IsTransparencySet(TO_BUILDINGS), |
199 BB_data[0] - sss->x_offset, BB_data[1] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset |
200 BB_data[0] - sss->x_offset, BB_data[1] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset |
200 ); |
201 ); |
201 } |
202 } |
202 |
203 |
203 /** Draws wires and, if required, pylons on a given tile |
204 /** Draws wires and, if required, pylons on a given tile |
263 continue; |
268 continue; |
264 } |
269 } |
265 |
270 |
266 /* We check whether the track in question (k) is present in the tile |
271 /* We check whether the track in question (k) is present in the tile |
267 * (TrackSourceTile) */ |
272 * (TrackSourceTile) */ |
268 if (HASBIT(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) { |
273 if (HasBit(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) { |
269 /* track found, if track is in the neighbour tile, adjust the number |
274 /* track found, if track is in the neighbour tile, adjust the number |
270 * of the PCP for preferred/allowed determination*/ |
275 * of the PCP for preferred/allowed determination*/ |
271 DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i); |
276 DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i); |
272 SETBIT(PCPstatus, i); // This PCP is in use |
277 SetBit(PCPstatus, i); // This PCP is in use |
273 |
278 |
274 PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos]; |
279 PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos]; |
275 PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos]; |
280 PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos]; |
276 } |
281 } |
277 } |
282 } |
278 |
283 |
279 /* Deactivate all PPPs if PCP is not used */ |
284 /* Deactivate all PPPs if PCP is not used */ |
280 PPPpreferred[i] *= HASBIT(PCPstatus, i); |
285 PPPpreferred[i] *= HasBit(PCPstatus, i); |
281 PPPallowed[i] *= HASBIT(PCPstatus, i); |
286 PPPallowed[i] *= HasBit(PCPstatus, i); |
282 |
287 |
283 /* A station is always "flat", so adjust the tileh accordingly */ |
288 /* A station is always "flat", so adjust the tileh accordingly */ |
284 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
289 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
285 |
290 |
286 /* Read the foundataions if they are present, and adjust the tileh */ |
291 /* Read the foundataions if they are present, and adjust the tileh */ |
288 if (IsBridgeTile(neighbour)) { |
293 if (IsBridgeTile(neighbour)) { |
289 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); |
294 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); |
290 } |
295 } |
291 |
296 |
292 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); |
297 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); |
|
298 |
|
299 /* Half tile slopes coincide only with horizontal/vertical track. |
|
300 * Faking a flat slope results in the correct sprites on positions. */ |
|
301 if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
293 |
302 |
294 AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]); |
303 AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]); |
295 |
304 |
296 /* If we have a straight (and level) track, we want a pylon only every 2 tiles |
305 /* If we have a straight (and level) track, we want a pylon only every 2 tiles |
297 * Delete the PCP if this is the case. */ |
306 * Delete the PCP if this is the case. */ |
298 /* Level means that the slope is the same, or the track is flat */ |
307 /* Level means that the slope is the same, or the track is flat */ |
299 if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) { |
308 if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) { |
300 for (k = 0; k < NUM_IGNORE_GROUPS; k++) |
309 for (k = 0; k < NUM_IGNORE_GROUPS; k++) |
301 if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) CLRBIT(PCPstatus, i); |
310 if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) ClrBit(PCPstatus, i); |
302 } |
311 } |
303 |
312 |
304 /* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist. |
313 /* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist. |
305 * In that case, we try the any of the allowed ones. if they don't exist either, don't draw |
314 * In that case, we try the any of the allowed ones. if they don't exist either, don't draw |
306 * anything. Note that the preferred PPPs still contain the end-of-line markers. |
315 * anything. Note that the preferred PPPs still contain the end-of-line markers. |
311 Track bridgetrack = GetBridgeAxis(ti->tile) == AXIS_X ? TRACK_X : TRACK_Y; |
320 Track bridgetrack = GetBridgeAxis(ti->tile) == AXIS_X ? TRACK_X : TRACK_Y; |
312 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile)); |
321 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile)); |
313 |
322 |
314 if ((height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) && |
323 if ((height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) && |
315 (i == PCPpositions[bridgetrack][0] || i == PCPpositions[bridgetrack][1])) { |
324 (i == PCPpositions[bridgetrack][0] || i == PCPpositions[bridgetrack][1])) { |
316 SETBIT(OverridePCP, i); |
325 SetBit(OverridePCP, i); |
317 } |
326 } |
318 } |
327 } |
319 |
328 |
320 if (PPPallowed[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) { |
329 if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i)) { |
321 for (k = 0; k < DIR_END; k++) { |
330 for (k = 0; k < DIR_END; k++) { |
322 byte temp = PPPorder[i][GetTLG(ti->tile)][k]; |
331 byte temp = PPPorder[i][GetTLG(ti->tile)][k]; |
323 |
332 |
324 if (HASBIT(PPPallowed[i], temp)) { |
333 if (HasBit(PPPallowed[i], temp)) { |
325 uint x = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp]; |
334 uint x = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp]; |
326 uint y = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp]; |
335 uint y = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp]; |
327 |
336 |
328 /* Don't build the pylon if it would be outside the tile */ |
337 /* Don't build the pylon if it would be outside the tile */ |
329 if (!HASBIT(OwnedPPPonPCP[i], temp)) { |
338 if (!HasBit(OwnedPPPonPCP[i], temp)) { |
330 /* We have a neighour that will draw it, bail out */ |
339 /* We have a neighour that will draw it, bail out */ |
331 if (trackconfig[TS_NEIGHBOUR] != 0) break; |
340 if (trackconfig[TS_NEIGHBOUR] != 0) break; |
332 continue; /* No neighbour, go looking for a better position */ |
341 continue; /* No neighbour, go looking for a better position */ |
333 } |
342 } |
334 |
343 |
335 AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, |
344 AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, |
336 GetPCPElevation(ti->tile, i), |
345 GetPCPElevation(ti->tile, i), |
337 HASBIT(_transparent_opt, TO_BUILDINGS), -1, -1); |
346 IsTransparencySet(TO_BUILDINGS), -1, -1); |
338 break; /* We already have drawn a pylon, bail out */ |
347 break; /* We already have drawn a pylon, bail out */ |
339 } |
348 } |
340 } |
349 } |
341 } |
350 } |
342 } |
351 } |
343 |
352 |
344 /* Don't draw a wire under a low bridge */ |
353 /* Don't draw a wire under a low bridge */ |
345 if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !HASBIT(_transparent_opt, TO_BUILDINGS)) { |
354 if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_BUILDINGS)) { |
346 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile)); |
355 uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile)); |
347 |
356 |
348 if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return; |
357 if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return; |
349 } |
358 } |
350 |
359 |
351 /* Drawing of pylons is finished, now draw the wires */ |
360 /* Drawing of pylons is finished, now draw the wires */ |
352 for (t = TRACK_BEGIN; t < TRACK_END; t++) { |
361 for (t = TRACK_BEGIN; t < TRACK_END; t++) { |
353 if (HASBIT(trackconfig[TS_HOME], t)) { |
362 if (HasBit(trackconfig[TS_HOME], t)) { |
354 if (IsTunnelTile(ti->tile)) break; // drawn together with tunnel-roof (see DrawCatenaryOnTunnel()) |
363 if (IsTunnelTile(ti->tile)) break; // drawn together with tunnel-roof (see DrawCatenaryOnTunnel()) |
355 byte PCPconfig = HASBIT(PCPstatus, PCPpositions[t][0]) + |
364 byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) + |
356 (HASBIT(PCPstatus, PCPpositions[t][1]) << 1); |
365 (HasBit(PCPstatus, PCPpositions[t][1]) << 1); |
357 |
366 |
358 const SortableSpriteStruct *sss; |
367 const SortableSpriteStruct *sss; |
359 int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */ |
368 int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */ |
360 |
369 |
361 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ |
370 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ |
367 * Therefore it is save to use GetSlopeZ() for the elevation. |
376 * Therefore it is save to use GetSlopeZ() for the elevation. |
368 * Also note, that the result of GetSlopeZ() is very special for bridge-ramps. |
377 * Also note, that the result of GetSlopeZ() is very special for bridge-ramps. |
369 */ |
378 */ |
370 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
379 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
371 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset, |
380 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset, |
372 HASBIT(_transparent_opt, TO_BUILDINGS)); |
381 IsTransparencySet(TO_BUILDINGS)); |
373 } |
382 } |
374 } |
383 } |
375 } |
384 } |
376 |
385 |
377 static void DrawCatenaryOnBridge(const TileInfo *ti) |
386 static void DrawCatenaryOnBridge(const TileInfo *ti) |
400 |
409 |
401 height = GetBridgeHeight(end); |
410 height = GetBridgeHeight(end); |
402 |
411 |
403 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
412 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
404 sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset, |
413 sss->x_size, sss->y_size, sss->z_size, height + sss->z_offset, |
405 HASBIT(_transparent_opt, TO_BUILDINGS) |
414 IsTransparencySet(TO_BUILDINGS) |
406 ); |
415 ); |
407 |
416 |
408 /* Finished with wires, draw pylons */ |
417 /* Finished with wires, draw pylons */ |
409 /* every other tile needs a pylon on the northern end */ |
418 /* every other tile needs a pylon on the northern end */ |
410 if (num % 2) { |
419 if (num % 2) { |
411 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_NE : DIAGDIR_NW); |
420 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_NE : DIAGDIR_NW); |
412 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
421 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
413 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
422 if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
414 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
423 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
415 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
424 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
416 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, HASBIT(_transparent_opt, TO_BUILDINGS), -1, -1); |
425 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_BUILDINGS), -1, -1); |
417 } |
426 } |
418 |
427 |
419 /* need a pylon on the southern end of the bridge */ |
428 /* need a pylon on the southern end of the bridge */ |
420 if (DistanceMax(ti->tile, start) == length) { |
429 if (DistanceMax(ti->tile, start) == length) { |
421 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_SW : DIAGDIR_SE); |
430 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_SW : DIAGDIR_SE); |
422 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
431 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
423 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
432 if (HasBit(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
424 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
433 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
425 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
434 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
426 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, HASBIT(_transparent_opt, TO_BUILDINGS), -1, -1); |
435 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_BUILDINGS), -1, -1); |
427 } |
436 } |
428 } |
437 } |
429 |
438 |
430 void DrawCatenary(const TileInfo *ti) |
439 void DrawCatenary(const TileInfo *ti) |
431 { |
440 { |
447 /* This wire is not visible with the default depot sprites */ |
456 /* This wire is not visible with the default depot sprites */ |
448 AddSortableSpriteToDraw( |
457 AddSortableSpriteToDraw( |
449 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
458 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
450 sss->x_size, sss->y_size, sss->z_size, |
459 sss->x_size, sss->y_size, sss->z_size, |
451 GetTileMaxZ(ti->tile) + sss->z_offset, |
460 GetTileMaxZ(ti->tile) + sss->z_offset, |
452 HASBIT(_transparent_opt, TO_BUILDINGS) |
461 IsTransparencySet(TO_BUILDINGS) |
453 ); |
462 ); |
454 return; |
463 return; |
455 } |
464 } |
456 break; |
465 break; |
457 |
466 |