diff --git a/src/f_finale.c b/src/f_finale.c index 54f90e07a..be90017f8 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2173,7 +2173,7 @@ void F_TitleScreenTicker(boolean run) camera[0].y = cameraref->y; camera[0].z = cameraref->z; camera[0].angle = cameraref->angle; - camera[0].aiming = cameraref->cusval; + camera[0].aiming = cameraref->pitch; camera[0].subsector = cameraref->subsector; } else @@ -3154,8 +3154,34 @@ boolean F_StartCeremony(void) globalweather = mapheaderinfo[gamemap-1]->weather; G_DoLoadLevelEx(false, GS_CEREMONY); + + r_splitscreen = 0; // Only one screen for the ceremony + R_ExecuteSetViewSize(); return true; } return false; } + +void F_CeremonyTicker(boolean run) +{ + (void)run; + + // don't trigger if doing anything besides idling + if (gameaction != ga_nothing || gamestate != GS_CEREMONY) + { + return; + } + + P_TickAltView(&titlemapcam); + + if (titlemapcam.mobj != NULL) + { + camera[0].x = titlemapcam.mobj->x; + camera[0].y = titlemapcam.mobj->y; + camera[0].z = titlemapcam.mobj->z; + camera[0].angle = titlemapcam.mobj->angle; + camera[0].aiming = titlemapcam.mobj->pitch; + camera[0].subsector = titlemapcam.mobj->subsector; + } +} diff --git a/src/f_finale.h b/src/f_finale.h index 9b5ef0691..e86e2ce5c 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -78,7 +78,9 @@ void F_StartIntro(void); void F_StartTitleScreen(void); void F_StartEnding(void); void F_StartCredits(void); + boolean F_StartCeremony(void); +void F_CeremonyTicker(boolean run); extern INT32 finalecount; extern INT32 titlescrollxspeed; diff --git a/src/g_game.c b/src/g_game.c index 48692590a..fadc35acd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2236,8 +2236,7 @@ void G_Ticker(boolean run) case GS_CEREMONY: P_Ticker(run); - ST_Ticker(run); - HU_Ticker(); + F_CeremonyTicker(run); break; case GS_WAITINGPLAYERS: diff --git a/src/info.c b/src/info.c index d0509e731..a400c4cc2 100644 --- a/src/info.c +++ b/src/info.c @@ -21281,7 +21281,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 10, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOGRAVITY, // flags + MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate }, diff --git a/src/p_local.h b/src/p_local.h index 12362a548..eb4633ff4 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -197,6 +197,8 @@ void P_HaltPlayerOrbit(player_t *player); void P_ExitPlayerOrbit(player_t *player); boolean P_PlayerOrbit(player_t *player); +void P_TickAltView(altview_t *view); + void P_MovePlayer(player_t *player); void P_PlayerThink(player_t *player); void P_PlayerAfterThink(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index 4433e1c64..cc0faf8df 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -47,6 +47,7 @@ #include "k_objects.h" #include "k_grandprix.h" #include "k_director.h" +#include "m_easing.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); @@ -3782,12 +3783,13 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam) else if (player->awayview.tics && player->awayview.mobj && !P_MobjWasRemoved(player->awayview.mobj)) // Camera must obviously exist { camera_t dummycam; + dummycam.subsector = player->awayview.mobj->subsector; dummycam.x = player->awayview.mobj->x; dummycam.y = player->awayview.mobj->y; dummycam.z = player->awayview.mobj->z; - //dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT - dummycam.height = 0; // Why? Remote viewpoint cameras have no height. + dummycam.height = 0; + // Are we in water? if (P_CameraCheckWater(&dummycam)) postimg = postimg_water; @@ -9487,6 +9489,61 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_MONITOR_PART: Obj_MonitorPartThink(mobj); break; + case MT_ALTVIEWMAN: + { + mobj->momx = mobj->momy = mobj->momz = 0; + + if (mobj->tracer != NULL && P_MobjWasRemoved(mobj->tracer) == false) + { + fixed_t dist = P_AproxDistance( + P_AproxDistance( + mobj->tracer->x - mobj->x, + mobj->tracer->y - mobj->y + ), + mobj->tracer->z - mobj->z + ); + + mobj->angle = Easing_OutSine(FRACUNIT/8, mobj->angle, mobj->tracer->angle); + mobj->pitch = Easing_OutSine(FRACUNIT/8, mobj->pitch, mobj->tracer->pitch); + + if (dist > mobj->radius) + { + fixed_t newX = Easing_OutSine(FRACUNIT/8, mobj->x, mobj->tracer->x); + fixed_t newY = Easing_OutSine(FRACUNIT/8, mobj->y, mobj->tracer->y); + fixed_t newZ = Easing_OutSine(FRACUNIT/8, mobj->z, mobj->tracer->z); + + mobj->momx = newX - mobj->x; + mobj->momy = newY - mobj->y; + mobj->momz = newZ - mobj->z; + } + else + { + P_SetTarget(&mobj->tracer, P_GetNextTubeWaypoint(mobj->tracer, false)); + } + } + + // If target is valid, then we'll focus on it. + if (mobj->target != NULL && P_MobjWasRemoved(mobj->target) == false) + { + mobj->angle = R_PointToAngle2( + mobj->x, + mobj->y, + mobj->target->x, + mobj->target->y + ); + + mobj->pitch = R_PointToAngle2( + 0, + mobj->z, + R_PointToDist2( + mobj->x, mobj->y, + mobj->target->x, mobj->target->y + ), + mobj->target->z + (mobj->target->height >> 1) + ); + } + } + break; default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); @@ -10464,9 +10521,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) else switch (mobj->type) { - case MT_ALTVIEWMAN: - if (titlemapinaction) mobj->flags &= ~MF_NOTHINK; - break; case MT_LOCKONINF: P_SetScale(mobj, (mobj->destscale = 3*mobj->scale)); break; diff --git a/src/p_spec.c b/src/p_spec.c index 60c261ad8..74397cd8f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2997,7 +2997,7 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha altview_t *modifyView = NULL; mobj_t *newViewMobj = NULL; - if (titlemapinaction) + if (gamestate != GS_LEVEL) { modifyView = &titlemapcam; } @@ -3018,11 +3018,98 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha P_SetTarget(&modifyView->mobj, newViewMobj); - // If titlemap, awayview.tics is ignored - if (titlemapinaction == false) + if (gamestate != GS_LEVEL) + { + // If titlemap, awayview.tics is ignored + modifyView->tics = -1; + } + else { modifyView->tics = args[1]; } + + if (args[2] != 0) + { + switch (args[2]) + { + case -1: + { + mobj_t *firstPlace = NULL; + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + player_t *player = NULL; + + if (playeringame[i] == false) + { + continue; + } + + player = &players[i]; + if (player->spectator == true) + { + continue; + } + + if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) + { + continue; + } + + if (player->position == 1) + { + firstPlace = player->mo; + break; + } + } + + P_SetTarget( + &newViewMobj->target, + firstPlace + ); + break; + } + case -2: + { + mobj_t *consoleMo = NULL; + if (playeringame[consoleplayer] == true) + { + consoleMo = players[consoleplayer].mo; + } + + P_SetTarget( + &newViewMobj->target, + consoleMo + ); + break; + } + default: + { + P_SetTarget( + &newViewMobj->target, + P_FindMobjFromTID(args[2], NULL, NULL) + ); + break; + } + } + } + else + { + P_SetTarget(&newViewMobj->target, NULL); + } + + if (args[3] > 0 && args[3] <= NUMTUBEWAYPOINTSEQUENCES) + { + P_SetTarget( + &newViewMobj->tracer, + P_GetFirstTubeWaypoint(args[3] - 1) + ); + } + else + { + P_SetTarget(&newViewMobj->tracer, NULL); + } } break; diff --git a/src/p_user.c b/src/p_user.c index fcf035850..0a2c5b548 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3997,6 +3997,25 @@ DoABarrelRoll (player_t *player) player->tilt = slope; } +void P_TickAltView(altview_t *view) +{ + if (view->mobj != NULL && P_MobjWasRemoved(view->mobj) == true) + { + P_SetTarget(&view->mobj, NULL); // remove view->mobj asap if invalid + view->tics = 0; // reset to zero + } + + if (view->tics > 0) + { + view->tics--; + + if (view->tics == 0) + { + P_SetTarget(&view->mobj, NULL); + } + } +} + // // P_PlayerThink // @@ -4020,18 +4039,11 @@ void P_PlayerThink(player_t *player) player->old_drawangle = player->drawangle; - if (player->awayview.mobj && P_MobjWasRemoved(player->awayview.mobj)) - { - P_SetTarget(&player->awayview.mobj, NULL); // remove awayview.mobj asap if invalid - player->awayview.tics = 0; // reset to zero - } + P_TickAltView(&player->awayview); if (player->flashcount) player->flashcount--; - if (player->awayview.tics && player->awayview.tics != -1) - player->awayview.tics--; - // Track airtime if (P_IsObjectOnGround(player->mo) && !P_PlayerInPain(player)) // This isn't airtime, but it's control loss all the same.