src/landscape.cpp
changeset 8266 48fa6a084b98
parent 8263 cf890c002a88
child 8383 77460afa773a
equal deleted inserted replaced
8265:9d7c69a31cdc 8266:48fa6a084b98
    74 	if (IsLeveledFoundation(f)) {
    74 	if (IsLeveledFoundation(f)) {
    75 		*s = SLOPE_FLAT;
    75 		*s = SLOPE_FLAT;
    76 		return TILE_HEIGHT;
    76 		return TILE_HEIGHT;
    77 	}
    77 	}
    78 
    78 
       
    79 	if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
       
    80 		*s = HalftileSlope(*s, GetHalftileFoundationCorner(f));
       
    81 		return 0;
       
    82 	}
       
    83 
       
    84 	if (IsSpecialRailFoundation(f)) {
       
    85 		*s = SlopeWithThreeCornersRaised(OppositeCorner(GetRailFoundationCorner(f)));
       
    86 		return 0;
       
    87 	}
       
    88 
    79 	uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
    89 	uint dz = IsSteepSlope(*s) ? TILE_HEIGHT : 0;
    80 	Corner highest_corner = GetHighestSlopeCorner(*s);
    90 	Corner highest_corner = GetHighestSlopeCorner(*s);
    81 
    91 
    82 	switch (f) {
    92 	switch (f) {
    83 		case FOUNDATION_INCLINED_X:
    93 		case FOUNDATION_INCLINED_X:
    90 
   100 
    91 		case FOUNDATION_STEEP_LOWER:
   101 		case FOUNDATION_STEEP_LOWER:
    92 			*s = SlopeWithOneCornerRaised(highest_corner);
   102 			*s = SlopeWithOneCornerRaised(highest_corner);
    93 			break;
   103 			break;
    94 
   104 
    95 		case FOUNDATION_STEEP_HIGHER:
   105 		case FOUNDATION_STEEP_BOTH:
    96 			*s = SlopeWithThreeCornersRaised(OppositeCorner(highest_corner));
   106 			*s = HalftileSlope(SlopeWithOneCornerRaised(highest_corner), highest_corner);
    97 			break;
   107 			break;
    98 
   108 
    99 		default: NOT_REACHED();
   109 		default: NOT_REACHED();
   100 	}
   110 	}
   101 	return dz;
   111 	return dz;
   224 uint GetSlopeZ(int x, int y)
   234 uint GetSlopeZ(int x, int y)
   225 {
   235 {
   226 	TileIndex tile = TileVirtXY(x, y);
   236 	TileIndex tile = TileVirtXY(x, y);
   227 
   237 
   228 	return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
   238 	return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
       
   239 }
       
   240 
       
   241 /**
       
   242  * Determine the Z height of a corner relative to TileZ.
       
   243  *
       
   244  * @pre The slope must not be a halftile slope.
       
   245  *
       
   246  * @param tileh The slope.
       
   247  * @param corner The corner.
       
   248  * @return Z position of corner relative to TileZ.
       
   249  */
       
   250 int GetSlopeZInCorner(Slope tileh, Corner corner)
       
   251 {
       
   252 	assert(!IsHalftileSlope(tileh));
       
   253 	static const int _corner_slopes[4][2] = {
       
   254 		{ SLOPE_W, SLOPE_STEEP_W }, { SLOPE_S, SLOPE_STEEP_S }, { SLOPE_E, SLOPE_STEEP_E }, { SLOPE_N, SLOPE_STEEP_N }
       
   255 	};
       
   256 	return ((tileh & _corner_slopes[corner][0]) != 0 ? TILE_HEIGHT : 0) + (tileh == _corner_slopes[corner][1] ? TILE_HEIGHT : 0);
   229 }
   257 }
   230 
   258 
   231 /**
   259 /**
   232  * Determine the Z height of the corners of a specific tile edge
   260  * Determine the Z height of the corners of a specific tile edge
   233  *
   261  *
   306 
   334 
   307 void DrawFoundation(TileInfo *ti, Foundation f)
   335 void DrawFoundation(TileInfo *ti, Foundation f)
   308 {
   336 {
   309 	if (!IsFoundation(f)) return;
   337 	if (!IsFoundation(f)) return;
   310 
   338 
       
   339 	/* Two part foundations must be drawn separately */
       
   340 	assert(f != FOUNDATION_STEEP_BOTH);
       
   341 
   311 	uint sprite_block = 0;
   342 	uint sprite_block = 0;
   312 	uint z;
   343 	uint z;
   313 	Slope slope = GetFoundationSlope(ti->tile, &z);
   344 	Slope slope = GetFoundationSlope(ti->tile, &z);
   314 
   345 
   315 	/* Select the needed block of foundations sprites
   346 	/* Select the needed block of foundations sprites
   322 	if (!HasFoundationNE(ti->tile, slope, z)) sprite_block += 2;
   353 	if (!HasFoundationNE(ti->tile, slope, z)) sprite_block += 2;
   323 
   354 
   324 	/* Use the original slope sprites if NW and NE borders should be visible */
   355 	/* Use the original slope sprites if NW and NE borders should be visible */
   325 	SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * SPR_TRKFOUND_BLOCK_SIZE));
   356 	SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * SPR_TRKFOUND_BLOCK_SIZE));
   326 	SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SPR_SLOPES_INCLINED_OFFSET + sprite_block * SPR_TRKFOUND_BLOCK_SIZE;
   357 	SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SPR_SLOPES_INCLINED_OFFSET + sprite_block * SPR_TRKFOUND_BLOCK_SIZE;
   327 	//SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
   358 	SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
   328 
   359 
   329 	if (IsSteepSlope(ti->tileh)) {
   360 	if (IsSteepSlope(ti->tileh)) {
   330 		/* Lower part of foundation */
   361 		if (!IsNonContinuousFoundation(f)) {
   331 		AddSortableSpriteToDraw(
   362 			/* Lower part of foundation */
   332 			leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
   363 			AddSortableSpriteToDraw(
   333 		);
   364 				leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
       
   365 			);
       
   366 		}
   334 
   367 
   335 		Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
   368 		Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
   336 		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
   369 		ti->z += ApplyFoundationToSlope(f, &ti->tileh);
   337 
   370 
   338 		if (IsInclinedFoundation(f)) {
   371 		if (IsInclinedFoundation(f)) {
   339 			/* inclined foundation */
   372 			/* inclined foundation */
   340 			byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
   373 			byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
   341 
   374 
   342 			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
   375 			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
   343 			OffsetGroundSprite(31, 9);
   376 			OffsetGroundSprite(31, 9);
   344 		} else if (f >= FOUNDATION_STEEP_HIGHER) {
   377 		} else if (f == FOUNDATION_STEEP_LOWER) {
   345 			/* three corners raised:
       
   346 			 * Draw inclined foundations for both axes, that results in the needed image.
       
   347 			 */
       
   348 			SpriteID upper = inclined_base + highest_corner * 2;
       
   349 
       
   350 			AddSortableSpriteToDraw(upper, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
       
   351 			AddChildSpriteScreen(upper + 1, PAL_NONE, 31, 9);
       
   352 			OffsetGroundSprite(31, 9);
       
   353 		} else {
       
   354 			/* one corner raised */
   378 			/* one corner raised */
   355 			OffsetGroundSprite(31, 1);
   379 			OffsetGroundSprite(31, 1);
       
   380 		} else {
       
   381 			/* halftile foundation */
       
   382 			int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0);
       
   383 			int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0);
       
   384 
       
   385 			AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT);
       
   386 			OffsetGroundSprite(31, 9);
   356 		}
   387 		}
   357 	} else {
   388 	} else {
   358 		if (IsLeveledFoundation(f)) {
   389 		if (IsLeveledFoundation(f)) {
   359 			/* leveled foundation */
   390 			/* leveled foundation */
   360 			AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
   391 			AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
   361 			OffsetGroundSprite(31, 1);
   392 			OffsetGroundSprite(31, 1);
       
   393 		} else if (IsNonContinuousFoundation(f)) {
       
   394 			/* halftile foundation */
       
   395 			Corner halftile_corner = GetHalftileFoundationCorner(f);
       
   396 			int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0);
       
   397 			int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0);
       
   398 
       
   399 			AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z);
       
   400 			OffsetGroundSprite(31, 9);
       
   401 		} else if (IsSpecialRailFoundation(f)) {
       
   402 			/* anti-zig-zag foundation */
       
   403 			SpriteID spr;
       
   404 			if (ti->tileh == SLOPE_NS || ti->tileh == SLOPE_EW) {
       
   405 				/* half of leveled foundation under track corner */
       
   406 				spr = leveled_base + SlopeWithThreeCornersRaised(GetRailFoundationCorner(f));
       
   407 			} else {
       
   408 				/* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
       
   409 				spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
       
   410 			}
       
   411 			AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
       
   412 			OffsetGroundSprite(31, 9);
   362 		} else {
   413 		} else {
   363 			/* inclined foundation */
   414 			/* inclined foundation */
   364 			byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
   415 			byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
   365 
   416 
   366 			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);
   417 			AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z);