mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
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
c758a8ad27
commit
0e57da56b0
5 changed files with 106 additions and 0 deletions
|
|
@ -465,6 +465,15 @@ typedef enum
|
||||||
BOT_ITEM_PR__MAX
|
BOT_ITEM_PR__MAX
|
||||||
} botItemPriority_e;
|
} botItemPriority_e;
|
||||||
|
|
||||||
|
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
|
// player_t struct for loop state
|
||||||
typedef struct {
|
typedef struct {
|
||||||
fixed_t radius;
|
fixed_t radius;
|
||||||
|
|
@ -474,6 +483,7 @@ typedef struct {
|
||||||
vector2_t origin_shift;
|
vector2_t origin_shift;
|
||||||
vector2_t shift;
|
vector2_t shift;
|
||||||
boolean flip;
|
boolean flip;
|
||||||
|
sonicloopcamvars_t camera;
|
||||||
} sonicloopvars_t;
|
} sonicloopvars_t;
|
||||||
|
|
||||||
// player_t struct for power-ups
|
// player_t struct for power-ups
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ Obj_LoopEndpointCollide
|
||||||
{
|
{
|
||||||
player_t *player = toucher->player;
|
player_t *player = toucher->player;
|
||||||
sonicloopvars_t *s = &player->loop;
|
sonicloopvars_t *s = &player->loop;
|
||||||
|
sonicloopcamvars_t *cam = &s->camera;
|
||||||
|
|
||||||
mobj_t *anchor = end_anchor(end);
|
mobj_t *anchor = end_anchor(end);
|
||||||
mobj_t *center = anchor ? anchor_center(anchor) : NULL;
|
mobj_t *center = anchor ? anchor_center(anchor) : NULL;
|
||||||
|
|
@ -352,6 +353,17 @@ Obj_LoopEndpointCollide
|
||||||
|
|
||||||
s->flip = center_has_flip(center);
|
s->flip = center_has_flip(center);
|
||||||
|
|
||||||
|
cam->enter_tic = leveltime;
|
||||||
|
cam->exit_tic = INFTICS;
|
||||||
|
|
||||||
|
cam->zoom_out_speed = center->thing_args[2];
|
||||||
|
cam->zoom_in_speed = center->thing_args[3];
|
||||||
|
cam->dist = center->thing_args[4] * FRACUNIT;
|
||||||
|
cam->pan = FixedAngle(center->thing_args[5] * FRACUNIT);
|
||||||
|
cam->pan_speed = center->thing_args[6] * FRACUNIT;
|
||||||
|
cam->pan_accel = center->thing_args[7];
|
||||||
|
cam->pan_back = center->thing_args[8];
|
||||||
|
|
||||||
player->speed =
|
player->speed =
|
||||||
3 * (player->speed + toucher->momz) / 2;
|
3 * (player->speed + toucher->momz) / 2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ void P_HaltPlayerOrbit(player_t *player)
|
||||||
player->mo->flags &= ~(MF_NOCLIPHEIGHT);
|
player->mo->flags &= ~(MF_NOCLIPHEIGHT);
|
||||||
|
|
||||||
player->loop.radius = 0;
|
player->loop.radius = 0;
|
||||||
|
player->loop.camera.exit_tic = leveltime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_ExitPlayerOrbit(player_t *player)
|
void P_ExitPlayerOrbit(player_t *player)
|
||||||
|
|
|
||||||
|
|
@ -682,6 +682,17 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
WRITEFIXED(save->p, players[i].loop.shift.y);
|
WRITEFIXED(save->p, players[i].loop.shift.y);
|
||||||
WRITEUINT8(save->p, players[i].loop.flip);
|
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);
|
||||||
|
|
||||||
// ACS has read access to this, so it has to be net-communicated.
|
// ACS has read access to this, so it has to be net-communicated.
|
||||||
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
||||||
WRITEUINT32(save->p, players[i].roundconditions.unlocktriggers);
|
WRITEUINT32(save->p, players[i].roundconditions.unlocktriggers);
|
||||||
|
|
@ -1208,6 +1219,17 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
players[i].loop.shift.y = READFIXED(save->p);
|
players[i].loop.shift.y = READFIXED(save->p);
|
||||||
players[i].loop.flip = READUINT8(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);
|
||||||
|
|
||||||
// ACS has read access to this, so it has to be net-communicated.
|
// ACS has read access to this, so it has to be net-communicated.
|
||||||
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
||||||
players[i].roundconditions.unlocktriggers = READUINT32(save->p);
|
players[i].roundconditions.unlocktriggers = READUINT32(save->p);
|
||||||
|
|
|
||||||
61
src/p_user.c
61
src/p_user.c
|
|
@ -3072,6 +3072,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
fixed_t scaleDiff;
|
fixed_t scaleDiff;
|
||||||
fixed_t cameraScale = mapobjectscale;
|
fixed_t cameraScale = mapobjectscale;
|
||||||
|
|
||||||
|
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_x = thiscam->x;
|
||||||
thiscam->old_y = thiscam->y;
|
thiscam->old_y = thiscam->y;
|
||||||
thiscam->old_z = thiscam->z;
|
thiscam->old_z = thiscam->z;
|
||||||
|
|
@ -3196,6 +3200,58 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
camdist = FixedMul(cv_cam_dist[num].value, cameraScale);
|
camdist = FixedMul(cv_cam_dist[num].value, cameraScale);
|
||||||
camheight = FixedMul(cv_cam_height[num].value, cameraScale);
|
camheight = FixedMul(cv_cam_height[num].value, cameraScale);
|
||||||
|
|
||||||
|
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)
|
if (timeover)
|
||||||
{
|
{
|
||||||
const INT32 timeovercam = max(0, min(180, (player->karthud[khud_timeovercam] - 2*TICRATE)*15));
|
const INT32 timeovercam = max(0, min(180, (player->karthud[khud_timeovercam] - 2*TICRATE)*15));
|
||||||
|
|
@ -3878,6 +3934,11 @@ DoABarrelRoll (player_t *player)
|
||||||
|
|
||||||
fixed_t smoothing;
|
fixed_t smoothing;
|
||||||
|
|
||||||
|
if (player->loop.radius)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->respawn.state != RESPAWNST_NONE)
|
if (player->respawn.state != RESPAWNST_NONE)
|
||||||
{
|
{
|
||||||
player->tilt = 0;
|
player->tilt = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue