139 } |
139 } |
140 } |
140 } |
141 } |
141 } |
142 } |
142 } |
143 |
143 |
|
144 /** |
|
145 * Returns the Z position of a Pylon Control Point. |
|
146 * |
|
147 * @param tile The tile the pylon should stand on. |
|
148 * @param PCPpos The PCP of the tile. |
|
149 * @return The Z position of the PCP. |
|
150 */ |
|
151 static byte GetPCPElevation(TileIndex tile, DiagDirection PCPpos) |
|
152 { |
|
153 /* The elevation of the "pylon"-sprite should be the elevation at the PCP. |
|
154 * PCPs are always on a tile edge. |
|
155 * |
|
156 * This position can be outside of the tile, i.e. ?_pcp_offset == TILE_SIZE > TILE_SIZE - 1. |
|
157 * So we have to move it inside the tile, because if the neighboured tile has a foundation, |
|
158 * that does not smoothly connect to the current tile, we will get a wrong elevation from GetSlopeZ(). |
|
159 * |
|
160 * When we move the position inside the tile, we will get a wrong elevation if we have a slope. |
|
161 * To catch all cases we round the Z position to the next (TILE_HEIGHT / 2). |
|
162 * This will return the correct elevation for slopes and will also detect non-continuous elevation on edges. |
|
163 * |
|
164 * Also note that the result of GetSlopeZ() is very special on bridge-ramps. |
|
165 */ |
|
166 |
|
167 byte z = GetSlopeZ(TileX(tile) * TILE_SIZE + min(x_pcp_offsets[PCPpos], TILE_SIZE - 1), TileY(tile) * TILE_SIZE + min(y_pcp_offsets[PCPpos], TILE_SIZE - 1)); |
|
168 return (z + 2) & ~3; // this means z = (z + TILE_HEIGHT / 4) / (TILE_HEIGHT / 2) * (TILE_HEIGHT / 2); |
|
169 } |
|
170 |
144 /** Draws wires and, if required, pylons on a given tile |
171 /** Draws wires and, if required, pylons on a given tile |
145 * @param ti The Tileinfo to draw the tile for |
172 * @param ti The Tileinfo to draw the tile for |
146 */ |
173 */ |
147 static void DrawCatenaryRailway(const TileInfo *ti) |
174 static void DrawCatenaryRailway(const TileInfo *ti) |
148 { |
175 { |
182 /* Here's one of the main headaches. GetTileSlope does not correct for possibly |
209 /* Here's one of the main headaches. GetTileSlope does not correct for possibly |
183 * existing foundataions, so we do have to do that manually later on.*/ |
210 * existing foundataions, so we do have to do that manually later on.*/ |
184 tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL); |
211 tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL); |
185 trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); |
212 trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); |
186 if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; |
213 if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; |
|
214 |
|
215 /* If the neighboured tile does not smoothly connect to the current tile (because of a foundation), |
|
216 * we have to draw all pillars on the current tile. */ |
|
217 if (GetPCPElevation(ti->tile, i) != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; |
|
218 |
187 isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0); |
219 isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0); |
188 |
220 |
189 PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction) |
221 PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction) |
190 PPPallowed[i] = AllowedPPPonPCP[i]; |
222 PPPallowed[i] = AllowedPPPonPCP[i]; |
191 |
223 |
218 |
250 |
219 /* A station is always "flat", so adjust the tileh accordingly */ |
251 /* A station is always "flat", so adjust the tileh accordingly */ |
220 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
252 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
221 |
253 |
222 /* Read the foundataions if they are present, and adjust the tileh */ |
254 /* Read the foundataions if they are present, and adjust the tileh */ |
223 if (IsTileType(neighbour, MP_RAILWAY) && GetRailType(neighbour) == RAILTYPE_ELECTRIC) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); |
255 if (trackconfig[TS_NEIGHBOUR] != TRACK_BIT_NONE && IsTileType(neighbour, MP_RAILWAY) && GetRailType(neighbour) == RAILTYPE_ELECTRIC) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); |
224 if (IsBridgeTile(neighbour)) { |
256 if (IsBridgeTile(neighbour)) { |
225 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); |
257 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); |
226 } |
258 } |
227 |
259 |
228 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); |
260 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); |
266 /* We have a neighour that will draw it, bail out */ |
298 /* We have a neighour that will draw it, bail out */ |
267 if (trackconfig[TS_NEIGHBOUR] != 0) break; |
299 if (trackconfig[TS_NEIGHBOUR] != 0) break; |
268 continue; /* No neighbour, go looking for a better position */ |
300 continue; /* No neighbour, go looking for a better position */ |
269 } |
301 } |
270 |
302 |
271 AddSortableSpriteToDraw(pylons_normal[temp], PAL_NONE, x, y, 1, 1, 10, |
303 AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, 10, |
272 GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i]), |
304 GetPCPElevation(ti->tile, i), |
273 HASBIT(_transparent_opt, TO_BUILDINGS)); |
305 HASBIT(_transparent_opt, TO_BUILDINGS)); |
274 break; /* We already have drawn a pylon, bail out */ |
306 break; /* We already have drawn a pylon, bail out */ |
275 } |
307 } |
276 } |
308 } |
277 } |
309 } |
306 |
338 |
307 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ |
339 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ |
308 assert(!IsSteepSlope(tileh[TS_HOME])); |
340 assert(!IsSteepSlope(tileh[TS_HOME])); |
309 sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]]; |
341 sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]]; |
310 |
342 |
|
343 /* |
|
344 * The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE. |
|
345 * Therefore it is save to use GetSlopeZ() for the elevation. |
|
346 * Also note, that the result of GetSlopeZ() is very special for bridge-ramps. |
|
347 */ |
311 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
348 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
312 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, TILE_SIZE - 1), ti->y + min(sss->y_offset, TILE_SIZE - 1)) + sss->z_offset, |
349 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset, |
313 HASBIT(_transparent_opt, TO_BUILDINGS)); |
350 HASBIT(_transparent_opt, TO_BUILDINGS)); |
314 } |
351 } |
315 } |
352 } |
316 } |
353 } |
317 |
354 |
347 ); |
384 ); |
348 |
385 |
349 /* Finished with wires, draw pylons */ |
386 /* Finished with wires, draw pylons */ |
350 /* every other tile needs a pylon on the northern end */ |
387 /* every other tile needs a pylon on the northern end */ |
351 if (num % 2) { |
388 if (num % 2) { |
352 if (axis == AXIS_X) { |
389 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_NE : DIAGDIR_NW); |
353 AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
390 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
354 } else { |
391 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
355 AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
392 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
356 } |
393 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
|
394 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
357 } |
395 } |
358 |
396 |
359 /* need a pylon on the southern end of the bridge */ |
397 /* need a pylon on the southern end of the bridge */ |
360 if (DistanceMax(ti->tile, start) == length) { |
398 if (DistanceMax(ti->tile, start) == length) { |
361 if (axis == AXIS_X) { |
399 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_SW : DIAGDIR_SE); |
362 AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
400 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
363 } else { |
401 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
364 AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
402 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
365 } |
403 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
|
404 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); |
366 } |
405 } |
367 } |
406 } |
368 |
407 |
369 void DrawCatenary(const TileInfo *ti) |
408 void DrawCatenary(const TileInfo *ti) |
370 { |
409 { |
381 switch (GetTileType(ti->tile)) { |
420 switch (GetTileType(ti->tile)) { |
382 case MP_RAILWAY: |
421 case MP_RAILWAY: |
383 if (IsRailDepot(ti->tile)) { |
422 if (IsRailDepot(ti->tile)) { |
384 const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)]; |
423 const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)]; |
385 |
424 |
|
425 /* This wire is not visible with the default depot sprites */ |
386 AddSortableSpriteToDraw( |
426 AddSortableSpriteToDraw( |
387 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
427 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
388 sss->x_size, sss->y_size, sss->z_size, |
428 sss->x_size, sss->y_size, sss->z_size, |
389 GetTileMaxZ(ti->tile) + sss->z_offset, |
429 GetTileMaxZ(ti->tile) + sss->z_offset, |
390 HASBIT(_transparent_opt, TO_BUILDINGS) |
430 HASBIT(_transparent_opt, TO_BUILDINGS) |