diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 561daf058..b610d410c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1186,11 +1186,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) #ifdef USE_FTRANSFORM_ANGLEZ // Slope rotation from Kart p.anglez = 0.0f; - if (spr->mobj->standingslope) + if (spr->mobj->modeltilt) { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempz = spr->mobj->modeltilt->normal.z; + fixed_t tempy = spr->mobj->modeltilt->normal.y; + fixed_t tempx = spr->mobj->modeltilt->normal.x; fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); p.anglez = FIXED_TO_FLOAT(tempangle); tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); diff --git a/src/k_kart.c b/src/k_kart.c index 5ec49b444..12c4f14e0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4093,6 +4093,86 @@ static void K_MoveHeldObjects(player_t *player) if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) P_TeleportMove(cur, targx, targy, cur->z); +#ifdef ESLOPE + // We gotta do ALL of this... just so that bananas can tilt in OGL :V + if (P_IsObjectOnGround(cur)) + { + pslope_t *slope = NULL; + sector_t *sec = R_PointInSubsector(cur->x, cur->y)->sector; + boolean flip = (cur->eflags & MFE_VERTICALFLIP); + + if (flip) + { + if (sec->c_slope) + { + slope = sec->c_slope; + targz = P_GetZAt(sec->c_slope, cur->x, cur->y); + } + else + targz = sec->ceilingheight; + } + else + { + if (sec->f_slope) + { + slope = sec->f_slope; + targz = P_GetZAt(sec->f_slope, cur->x, cur->y); + } + else + targz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t surface; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!((rover->flags & FF_BLOCKOTHERS) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) + continue; + + if (flip) + { + surface = *rover->bottomheight; + if (*rover->b_slope) + surface = P_GetZAt(*rover->b_slope, cur->x, cur->y); + + if (surface < targz && surface > (cur->z + cur->height)) + { + targz = surface; + if (*rover->b_slope) + slope = *rover->b_slope; + } + } + else + { + surface = *rover->topheight; + if (*rover->t_slope) + surface = P_GetZAt(*rover->t_slope, cur->x, cur->y); + + if (surface > targz && surface < cur->z) + { + targz = surface; + if (*rover->t_slope) + slope = *rover->t_slope; + } + } + } + } + + cur->standingslope = slope; +#ifdef HWRENDER + cur->modeltilt = cur->standingslope; +#endif + } +#endif + cur = cur->hnext; } } @@ -4182,6 +4262,9 @@ static void K_MoveHeldObjects(player_t *player) P_TeleportMove(cur, targx, targy, targz); K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. +#ifdef HWRENDER + cur->modeltilt = player->mo->modeltilt; +#endif num = (num+1) % 2; cur = cur->hnext; } diff --git a/src/p_map.c b/src/p_map.c index 2c766349d..e7041afea 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2881,14 +2881,24 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) P_HandleSlopeLanding(thing, tmfloorslope); if (thing->momz <= 0) + { thing->standingslope = tmfloorslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif + } } else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) P_HandleSlopeLanding(thing, tmceilingslope); if (thing->momz >= 0) + { thing->standingslope = tmceilingslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif + } } } else // don't set standingslope if you're not going to clip against it @@ -4691,7 +4701,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if (!(rover->flags & FF_EXISTS)) continue; - if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) + if (!((rover->flags & FF_SOLID) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) continue; topheight = *rover->topheight; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1d0224590..dda3d045b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1816,6 +1816,9 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2389,6 +2392,9 @@ static boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } #endif @@ -6173,7 +6179,12 @@ void P_RunShadows(void) for (mobj = shadowcap; mobj; mobj = next) { - fixed_t floorz; + boolean flip; + fixed_t newz; + sector_t *sec; +#ifdef ESLOPE + pslope_t *slope = NULL; +#endif next = mobj->hnext; P_SetTarget(&mobj->hnext, NULL); @@ -6184,16 +6195,106 @@ void P_RunShadows(void) continue; // shouldn't you already be dead? } - if (mobj->target->player) - floorz = mobj->target->floorz; - else // FOR SOME REASON, plain floorz is not reliable for normal objects, only players?! - floorz = P_FloorzAtPos(mobj->target->x, mobj->target->y, mobj->target->z, mobj->target->height); - K_MatchGenericExtraFlags(mobj, mobj->target); + flip = (mobj->eflags & MFE_VERTICALFLIP); - if (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz) - || (!(mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z < floorz)) - mobj->flags2 |= MF2_DONTDRAW; + sec = R_PointInSubsector(mobj->target->x, mobj->target->y)->sector; + + if (flip) + { +#ifdef ESLOPE + if (sec->c_slope) + { + slope = sec->c_slope; + newz = P_GetZAt(sec->c_slope, mobj->target->x, mobj->target->y); + } + else +#endif + newz = sec->ceilingheight; + } + else + { +#ifdef ESLOPE + if (sec->f_slope) + { + slope = sec->f_slope; + newz = P_GetZAt(sec->f_slope, mobj->target->x, mobj->target->y); + } + else +#endif + newz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t surface; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if ((!(((rover->flags & FF_BLOCKPLAYER && mobj->target->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->target->player)) + || (rover->flags & FF_QUICKSAND)) + || (rover->flags & FF_SWIMMABLE))) + continue; + + if (flip) + { + surface = *rover->bottomheight; +#ifdef ESLOPE + if (*rover->b_slope) + surface = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y); +#endif + + if (surface < newz && surface > (mobj->target->z + mobj->target->height)) + { + newz = surface; +#ifdef ESLOPE + if (*rover->b_slope) + slope = *rover->b_slope; +#endif + } + } + else + { + surface = *rover->topheight; +#ifdef ESLOPE + if (*rover->t_slope) + surface = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y); +#endif + + if (surface > newz && surface < mobj->target->z) + { + newz = surface; +#ifdef ESLOPE + if (*rover->t_slope) + slope = *rover->t_slope; +#endif + } + } + } + } + + mobj->standingslope = slope; +#ifdef HWRENDER + mobj->modeltilt = mobj->standingslope; +#endif + + if (flip) + { + if ((mobj->target->z + mobj->target->height) > newz) + mobj->flags2 |= MF2_DONTDRAW; + } + else + { + if (mobj->target->z < newz) + mobj->flags2 |= MF2_DONTDRAW; + } // First scale to the same radius P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius)); @@ -6205,13 +6306,12 @@ void P_RunShadows(void) P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z); - if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height)) - || (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z))) + if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z)) { INT32 i; fixed_t prevz; - mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); + mobj->z = newz; for (i = 0; i < MAXFFLOORS; i++) { @@ -6223,7 +6323,7 @@ void P_RunShadows(void) // Check new position to see if you should still be on that ledge P_TeleportMove(mobj, dest->x, dest->y, mobj->z); - mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); + mobj->z = newz; if (mobj->z == prevz) break; @@ -8132,6 +8232,9 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); P_SetScale(mobj, mobj->target->scale); +#ifdef HWRENDER + mobj->modeltilt = mobj->target->modeltilt; +#endif { player_t *p = NULL; diff --git a/src/p_mobj.h b/src/p_mobj.h index dfc8fc738..aec2ed951 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -370,6 +370,9 @@ typedef struct mobj_s #ifdef ESLOPE struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) +#ifdef HWRENDER + struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. +#endif #endif boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 7d2e9a307..a3b80633a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2144,7 +2144,12 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); #ifdef ESLOPE if (diff2 & MD2_SLOPE) + { mobj->standingslope = P_SlopeById(READUINT16(save_p)); +#ifdef HWRENDER + mobj->modeltilt = mobj->standingslope; +#endif + } #endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); diff --git a/src/p_slopes.c b/src/p_slopes.c index 76af7bfde..47e624da9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -827,6 +827,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope thing->momz = -P_MobjFlip(thing); thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif } return; } @@ -843,6 +846,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momz = -P_MobjFlip(thing); thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif } } diff --git a/src/p_user.c b/src/p_user.c index 61d8f36f3..6802a9120 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1675,12 +1675,16 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->frame |= tr_trans50<fuse = ghost->info->damage; ghost->skin = mobj->skin; + ghost->standingslope = mobj->standingslope; +#ifdef HWRENDER + ghost->modeltilt = mobj->modeltilt; +#endif if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; if (!(mobj->flags & MF_DONTENCOREMAP)) - mobj->flags &= ~MF_DONTENCOREMAP; + ghost->flags &= ~MF_DONTENCOREMAP; return ghost; }