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
|
||||
} 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
|
||||
typedef struct {
|
||||
fixed_t radius;
|
||||
|
|
@ -474,6 +483,7 @@ typedef struct {
|
|||
vector2_t origin_shift;
|
||||
vector2_t shift;
|
||||
boolean flip;
|
||||
sonicloopcamvars_t camera;
|
||||
} sonicloopvars_t;
|
||||
|
||||
// player_t struct for power-ups
|
||||
|
|
|
|||
|
|
@ -295,6 +295,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;
|
||||
|
|
@ -352,6 +353,17 @@ Obj_LoopEndpointCollide
|
|||
|
||||
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 =
|
||||
3 * (player->speed + toucher->momz) / 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,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)
|
||||
|
|
|
|||
|
|
@ -682,6 +682,17 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
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);
|
||||
|
||||
// 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.
|
||||
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.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.
|
||||
// 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);
|
||||
|
|
|
|||
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 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_y = thiscam->y;
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
if (player->loop.radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawn.state != RESPAWNST_NONE)
|
||||
{
|
||||
player->tilt = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue