Extend cut-away view functionality

- arg2: TID of an object to make the camera's angle/pitch follow.
- arg3: Zoom tube waypoint sequence to start following.

- Ceremony uses one-screen, regardless of previous splitscreen-ed-ness
This commit is contained in:
Sally Coolatta 2023-02-27 18:59:34 -05:00
parent 82313de499
commit 9501b57296
8 changed files with 202 additions and 20 deletions

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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:

View file

@ -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
},

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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.