Loop camera
It zooms out, pans to the side and toward the player.
Loop Center thing:
- arg2: zoom-out speed in tics (zooms out when entering the loop)
- arg3: zoom-in speed in tics (zooms in when exiting the loop)
- arg4: zoom-out distance in fracunits (multiply by 65536)
- arg5: angle to pan to the side of the loop in degrees fracunits (multiply by 65536)
- This will be flipped depending on where the camera was
facing before entering the loop.
- arg6: panning speed in degrees fracunits (multiply by 65536)
- arg7: panning acceleration in tics (camera gradually pans to side of loop)
- arg8: panning deceleration in tics (camera gradually pans back to normal)
This commit is contained in:
parent
7dfa273dde
commit
dd7e3e4c26
5 changed files with 105 additions and 0 deletions
|
|
@ -278,6 +278,15 @@ typedef struct botvars_s
|
|||
|
||||
} botvars_t;
|
||||
|
||||
typedef struct {
|
||||
tic_t enter_tic, exit_tic;
|
||||
tic_t zoom_in_speed, zoom_out_speed;
|
||||
fixed_t dist;
|
||||
angle_t pan;
|
||||
fixed_t pan_speed; // in degrees
|
||||
tic_t pan_accel, pan_back;
|
||||
} sonicloopcamvars_t;
|
||||
|
||||
// player_t struct for loop state
|
||||
typedef struct {
|
||||
fixed_t radius;
|
||||
|
|
@ -286,6 +295,7 @@ typedef struct {
|
|||
vector3_t origin;
|
||||
vector2_t shift;
|
||||
boolean flip;
|
||||
sonicloopcamvars_t camera;
|
||||
} sonicloopvars_t;
|
||||
|
||||
// ========================================================================
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ Obj_LoopEndpointCollide
|
|||
{
|
||||
player_t *player = toucher->player;
|
||||
sonicloopvars_t *s = &player->loop;
|
||||
sonicloopcamvars_t *cam = &s->camera;
|
||||
|
||||
mobj_t *anchor = end_anchor(end);
|
||||
mobj_t *center = anchor ? anchor_center(anchor) : NULL;
|
||||
|
|
@ -272,6 +273,17 @@ Obj_LoopEndpointCollide
|
|||
|
||||
s->flip = center_has_flip(center);
|
||||
|
||||
cam->enter_tic = leveltime;
|
||||
cam->exit_tic = INFTICS;
|
||||
|
||||
cam->zoom_out_speed = center->spawnpoint->args[2];
|
||||
cam->zoom_in_speed = center->spawnpoint->args[3];
|
||||
cam->dist = center->spawnpoint->args[4] * FRACUNIT;
|
||||
cam->pan = FixedAngle(center->spawnpoint->args[5] * FRACUNIT);
|
||||
cam->pan_speed = center->spawnpoint->args[6] * FRACUNIT;
|
||||
cam->pan_accel = center->spawnpoint->args[7];
|
||||
cam->pan_back = center->spawnpoint->args[8];
|
||||
|
||||
player->speed =
|
||||
3 * (player->speed + toucher->momz) / 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ void P_HaltPlayerOrbit(player_t *player)
|
|||
player->mo->flags &= ~(MF_NOCLIPHEIGHT);
|
||||
|
||||
player->loop.radius = 0;
|
||||
player->loop.camera.exit_tic = leveltime;
|
||||
}
|
||||
|
||||
void P_ExitPlayerOrbit(player_t *player)
|
||||
|
|
|
|||
|
|
@ -370,6 +370,16 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEFIXED(save_p, players[i].loop.shift.y);
|
||||
WRITEUINT8(save_p, players[i].loop.flip);
|
||||
|
||||
// sonicloopcamvars_t
|
||||
WRITEUINT32(save_p, players[i].loop.camera.enter_tic);
|
||||
WRITEUINT32(save_p, players[i].loop.camera.exit_tic);
|
||||
WRITEUINT32(save_p, players[i].loop.camera.zoom_in_speed);
|
||||
WRITEUINT32(save_p, players[i].loop.camera.zoom_out_speed);
|
||||
WRITEFIXED(save_p, players[i].loop.camera.dist);
|
||||
WRITEANGLE(save_p, players[i].loop.camera.pan);
|
||||
WRITEFIXED(save_p, players[i].loop.camera.pan_speed);
|
||||
WRITEUINT32(save_p, players[i].loop.camera.pan_accel);
|
||||
WRITEUINT32(save_p, players[i].loop.camera.pan_back);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -648,6 +658,17 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].loop.shift.y = READFIXED(save_p);
|
||||
players[i].loop.flip = READUINT8(save_p);
|
||||
|
||||
// sonicloopcamvars_t
|
||||
players[i].loop.camera.enter_tic = READUINT32(save_p);
|
||||
players[i].loop.camera.exit_tic = READUINT32(save_p);
|
||||
players[i].loop.camera.zoom_in_speed = READUINT32(save_p);
|
||||
players[i].loop.camera.zoom_out_speed = READUINT32(save_p);
|
||||
players[i].loop.camera.dist = READFIXED(save_p);
|
||||
players[i].loop.camera.pan = READANGLE(save_p);
|
||||
players[i].loop.camera.pan_speed = READFIXED(save_p);
|
||||
players[i].loop.camera.pan_accel = READUINT32(save_p);
|
||||
players[i].loop.camera.pan_back = READUINT32(save_p);
|
||||
|
||||
//players[i].viewheight = P_GetPlayerViewHeight(players[i]); // scale cannot be factored in at this point
|
||||
}
|
||||
}
|
||||
|
|
|
|||
61
src/p_user.c
61
src/p_user.c
|
|
@ -3026,6 +3026,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
subsector_t *newsubsec;
|
||||
#endif
|
||||
|
||||
sonicloopcamvars_t *loop = &player->loop.camera;
|
||||
tic_t loop_out = leveltime - loop->enter_tic;
|
||||
tic_t loop_in = max(leveltime, loop->exit_tic) - loop->exit_tic;
|
||||
|
||||
thiscam->old_x = thiscam->x;
|
||||
thiscam->old_y = thiscam->y;
|
||||
thiscam->old_z = thiscam->z;
|
||||
|
|
@ -3147,6 +3151,58 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camdist = FixedMul(cv_cam_dist[num].value, mapobjectscale);
|
||||
camheight = FixedMul(cv_cam_height[num].value, mapobjectscale);
|
||||
|
||||
if (loop_in < loop->zoom_in_speed)
|
||||
{
|
||||
fixed_t f = loop_out < loop->zoom_out_speed
|
||||
? (loop_out * FRACUNIT) / loop->zoom_out_speed
|
||||
: FRACUNIT - ((loop_in * FRACUNIT) / loop->zoom_in_speed);
|
||||
|
||||
camspeed -= FixedMul(f, camspeed - (FRACUNIT/10));
|
||||
camdist += FixedMul(f, loop->dist);
|
||||
}
|
||||
|
||||
if (loop_in < max(loop->pan_back, 1))
|
||||
{
|
||||
fixed_t f = (loop_in * FRACUNIT) / max(loop->pan_back, 1);
|
||||
|
||||
fixed_t dx = mo->x - thiscam->x;
|
||||
fixed_t dy = mo->y - thiscam->y;
|
||||
|
||||
angle_t th = R_PointToAngle2(0, 0, dx, dy);
|
||||
fixed_t d = AngleFixed(focusangle - th);
|
||||
|
||||
if (d > 180*FRACUNIT)
|
||||
{
|
||||
d -= (360*FRACUNIT);
|
||||
}
|
||||
|
||||
focusangle = th + FixedAngle(FixedMul(f, d));
|
||||
|
||||
if (loop_in == 0)
|
||||
{
|
||||
focusaiming = R_PointToAngle2(0, thiscam->z, FixedHypot(dx, dy), mo->z);
|
||||
}
|
||||
}
|
||||
|
||||
if (loop_in == 0)
|
||||
{
|
||||
tic_t accel = max(loop->pan_accel, 1);
|
||||
fixed_t f = (min(loop_out, accel) * FRACUNIT) / accel;
|
||||
|
||||
INT32 turn = AngleDeltaSigned(focusangle, player->loop.yaw - loop->pan);
|
||||
INT32 turnspeed = FixedAngle(FixedMul(f, loop->pan_speed));
|
||||
|
||||
if (turn > turnspeed)
|
||||
{
|
||||
if (turn < ANGLE_90)
|
||||
{
|
||||
turnspeed = -(turnspeed);
|
||||
}
|
||||
|
||||
focusangle += turnspeed;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeover)
|
||||
{
|
||||
const INT32 timeovercam = max(0, min(180, (player->karthud[khud_timeovercam] - 2*TICRATE)*15));
|
||||
|
|
@ -4041,6 +4097,11 @@ DoABarrelRoll (player_t *player)
|
|||
|
||||
fixed_t smoothing;
|
||||
|
||||
if (player->loop.radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawn)
|
||||
{
|
||||
player->tilt = 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue