diff options
-rw-r--r-- | train_cmd.c | 2 | ||||
-rw-r--r-- | viewport.c | 35 |
2 files changed, 29 insertions, 8 deletions
diff --git a/train_cmd.c b/train_cmd.c index ded96b417..54945db93 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -119,7 +119,7 @@ void TrainConsistChanged(Vehicle *v) { veh_len = GetCallBackResult(CBID_VEH_LENGTH, u->engine_type, u); if (veh_len == CALLBACK_FAILED) veh_len = rvi_u->shorten_factor; - veh_len = clamp(veh_len, 0, 7); + veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code u->u.rail.cached_veh_length = 8 - veh_len; }; diff --git a/viewport.c b/viewport.c index b58d5da98..be0bbcf6e 100644 --- a/viewport.c +++ b/viewport.c @@ -1079,16 +1079,37 @@ static void ViewportSortParentSprites(ParentSpriteToDraw **psd) psd2 = psd; while ( (ps2=*++psd2) != NULL) { + bool mustswap = false; + if (ps2->unk16 & 1) continue; - if (ps->tile_right >= ps2->tile_x && - ps->tile_bottom >= ps2->tile_y && - ps->tile_z_bottom >= ps2->tile_z && ( - ps->tile_x >= ps2->tile_right || - ps->tile_y >= ps2->tile_bottom || - ps->tile_z >= ps2->tile_z_bottom - )) { + // Decide which sort order algorithm to use, based on whether the sprites have some overlapping area. + if (((ps2->tile_x > ps->tile_x && ps2->tile_x < ps->tile_right) || + (ps2->tile_right > ps->tile_x && ps2->tile_x < ps->tile_right)) && // overlap in X + ((ps2->tile_y > ps->tile_y && ps2->tile_y < ps->tile_bottom) || + (ps2->tile_bottom > ps->tile_y && ps2->tile_y < ps->tile_bottom)) && // overlap in Y + ((ps2->tile_z > ps->tile_z && ps2->tile_z < ps->tile_z_bottom) || + (ps2->tile_z_bottom > ps->tile_z && ps2->tile_z < ps->tile_z_bottom)) ) { // overlap in Z + // Sprites overlap. + // Use X+Y+Z as the sorting order, so sprites nearer the bottom of the screen, + // and with higher Z elevation, draw in front. + // Here X,Y,Z are the coordinates of the "center of mass" of the sprite, + // i.e. X=(left+right)/2, etc. + // However, since we only care about order, don't actually calculate the division / 2. + mustswap = ps->tile_x + ps->tile_right + ps->tile_y + ps->tile_bottom + ps->tile_z + ps->tile_z_bottom > + ps2->tile_x + ps2->tile_right + ps2->tile_y + ps2->tile_bottom + ps2->tile_z + ps2->tile_z_bottom; + } else { + // No overlap; use the original TTD sort algorithm. + mustswap = (ps->tile_right >= ps2->tile_x && + ps->tile_bottom >= ps2->tile_y && + ps->tile_z_bottom >= ps2->tile_z && + (ps->tile_x >= ps2->tile_right || + ps->tile_y >= ps2->tile_bottom || + ps->tile_z >= ps2->tile_z_bottom)); + } + if (mustswap) { + // Swap the two sprites ps and ps2 using bubble-sort algorithm. psd3 = psd; do { ps3 = *psd3; |