mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Player orbiting physics
This commit is contained in:
parent
e5a533544d
commit
b3511a9149
6 changed files with 211 additions and 3 deletions
|
|
@ -48,6 +48,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
p_floor.c
|
||||
p_inter.c
|
||||
p_lights.c
|
||||
p_loop.c
|
||||
p_map.c
|
||||
p_maputl.c
|
||||
p_mobj.c
|
||||
|
|
|
|||
|
|
@ -193,6 +193,10 @@ boolean P_AutoPause(void);
|
|||
void P_ElementalFire(player_t *player, boolean cropcircle);
|
||||
void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound);
|
||||
|
||||
void P_HaltPlayerOrbit(player_t *player);
|
||||
void P_ExitPlayerOrbit(player_t *player);
|
||||
boolean P_PlayerOrbit(player_t *player);
|
||||
|
||||
void P_MovePlayer(player_t *player);
|
||||
void P_PlayerThink(player_t *player);
|
||||
void P_PlayerAfterThink(player_t *player);
|
||||
|
|
|
|||
180
src/p_loop.c
Normal file
180
src/p_loop.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file p_loop.c
|
||||
/// \brief Sonic loop physics
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
#include "k_kart.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_slopes.h"
|
||||
#include "r_main.h"
|
||||
|
||||
static inline angle_t
|
||||
get_pitch (fixed_t revolution)
|
||||
{
|
||||
return FixedAngle((revolution & FRACMASK) * 360);
|
||||
}
|
||||
|
||||
static inline fixed_t
|
||||
get_shift_curve (const sonicloopvars_t *s)
|
||||
{
|
||||
const angle_t th = get_pitch(FixedDiv(
|
||||
s->revolution - s->min_revolution,
|
||||
s->max_revolution - s->min_revolution));
|
||||
|
||||
// XY shift is transformed on wave scale; less movement
|
||||
// at start and end of rotation, more halfway.
|
||||
return FSIN((th / 2) - ANGLE_90);
|
||||
}
|
||||
|
||||
void P_HaltPlayerOrbit(player_t *player)
|
||||
{
|
||||
// see P_PlayerOrbit
|
||||
player->mo->flags &= ~(MF_NOCLIPHEIGHT);
|
||||
|
||||
player->loop.radius = 0;
|
||||
}
|
||||
|
||||
void P_ExitPlayerOrbit(player_t *player)
|
||||
{
|
||||
sonicloopvars_t *s = &player->loop;
|
||||
|
||||
angle_t pitch = get_pitch(s->revolution);
|
||||
angle_t yaw = s->yaw;
|
||||
|
||||
fixed_t co, si;
|
||||
fixed_t speed;
|
||||
|
||||
if (s->radius < 0)
|
||||
{
|
||||
pitch += ANGLE_180;
|
||||
}
|
||||
|
||||
co = FCOS(pitch);
|
||||
si = FSIN(pitch);
|
||||
|
||||
speed = FixedMul(co, player->speed);
|
||||
|
||||
P_InstaThrust(player->mo, yaw, speed);
|
||||
|
||||
player->mo->momz = FixedMul(si, player->speed);
|
||||
|
||||
if (speed < 0)
|
||||
{
|
||||
yaw += ANGLE_180;
|
||||
}
|
||||
|
||||
// excludes only extremely vertical angles
|
||||
if (abs(co) * 4 > abs(si))
|
||||
{
|
||||
P_SetPlayerAngle(player, yaw);
|
||||
}
|
||||
|
||||
if (s->flip)
|
||||
{
|
||||
player->mo->eflags ^= MFE_VERTICALFLIP;
|
||||
player->mo->flags2 ^= MF2_OBJECTFLIP;
|
||||
|
||||
P_SetPitchRoll(player->mo,
|
||||
pitch + ANGLE_180, s->yaw);
|
||||
}
|
||||
|
||||
// tiregrease gives less friction, extends momentum
|
||||
player->tiregrease = TICRATE;
|
||||
|
||||
P_HaltPlayerOrbit(player);
|
||||
}
|
||||
|
||||
boolean P_PlayerOrbit(player_t *player)
|
||||
{
|
||||
sonicloopvars_t *s = &player->loop;
|
||||
|
||||
angle_t pitch;
|
||||
|
||||
fixed_t xy, z;
|
||||
fixed_t xs, ys;
|
||||
|
||||
fixed_t step, th, left;
|
||||
|
||||
fixed_t grav;
|
||||
|
||||
if (s->radius == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
grav = abs(P_GetMobjGravity(player->mo));
|
||||
|
||||
// Lose speed on the way up. revolution = 0.5 always
|
||||
// points straight up.
|
||||
if (abs(s->revolution & FRACMASK) < FRACUNIT/2)
|
||||
{
|
||||
player->speed -= grav;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->speed += 4 * grav;
|
||||
}
|
||||
|
||||
pitch = get_pitch(s->revolution);
|
||||
|
||||
xy = FixedMul(abs(s->radius), FSIN(pitch));
|
||||
z = FixedMul(abs(s->radius), -(FCOS(pitch)));
|
||||
|
||||
th = get_shift_curve(s);
|
||||
|
||||
xs = FixedMul(s->shift.x, th);
|
||||
ys = FixedMul(s->shift.y, th);
|
||||
|
||||
xs += FixedMul(xy, FCOS(s->yaw));
|
||||
ys += FixedMul(xy, FSIN(s->yaw));
|
||||
|
||||
P_MoveOrigin(player->mo,
|
||||
s->origin.x + xs,
|
||||
s->origin.y + ys,
|
||||
s->origin.z + z);
|
||||
|
||||
// Match rollangle to revolution
|
||||
P_SetPitchRoll(player->mo,
|
||||
s->radius < 0 ? (ANGLE_180 + pitch) : pitch,
|
||||
s->yaw);
|
||||
|
||||
// circumfrence = (2r)PI
|
||||
step = FixedDiv(player->speed,
|
||||
FixedMul(s->radius, M_TAU_FIXED));
|
||||
|
||||
left = (s->max_revolution - s->revolution);
|
||||
|
||||
if (abs(left) < abs(step))
|
||||
{
|
||||
P_ExitPlayerOrbit(player);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If player slows down by too much, throw them out of
|
||||
// the loop in a tumble.
|
||||
if (player->speed < player->mo->scale)
|
||||
{
|
||||
P_HaltPlayerOrbit(player);
|
||||
K_StumblePlayer(player);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
s->revolution += step;
|
||||
|
||||
// We need to not clip the ground. It sucks but setting
|
||||
// this flag is the only way to do that.
|
||||
player->mo->flags |= (MF_NOCLIPHEIGHT);
|
||||
|
||||
return true;
|
||||
}
|
||||
18
src/p_map.c
18
src/p_map.c
|
|
@ -2674,6 +2674,22 @@ fixed_t P_GetThingStepUp(mobj_t *thing, fixed_t destX, fixed_t destY)
|
|||
return maxstep;
|
||||
}
|
||||
|
||||
static boolean P_UsingStepUp(mobj_t *thing)
|
||||
{
|
||||
if (thing->flags & MF_NOCLIP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// orbits have no collision
|
||||
if (thing->player && thing->player->loop.radius)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
increment_move
|
||||
( mobj_t * thing,
|
||||
|
|
@ -2734,7 +2750,7 @@ increment_move
|
|||
// copy into the spechitint buffer from spechit
|
||||
spechitint_copyinto();
|
||||
|
||||
if (!(thing->flags & MF_NOCLIP))
|
||||
if (P_UsingStepUp(thing))
|
||||
{
|
||||
// All things are affected by their scale.
|
||||
fixed_t maxstep = P_GetThingStepUp(thing, tryx, tryy);
|
||||
|
|
|
|||
|
|
@ -3979,7 +3979,8 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj)
|
|||
static void P_SquishThink(mobj_t *mobj)
|
||||
{
|
||||
if (!(mobj->flags & MF_NOSQUISH) &&
|
||||
!(mobj->eflags & MFE_SLOPELAUNCHED))
|
||||
!(mobj->eflags & MFE_SLOPELAUNCHED) &&
|
||||
!(mobj->player && mobj->player->loop.radius != 0))
|
||||
{
|
||||
K_Squish(mobj);
|
||||
}
|
||||
|
|
@ -4002,7 +4003,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
|||
|
||||
// Zoom tube
|
||||
if ((mobj->player->carry == CR_ZOOMTUBE && mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
|| mobj->player->respawn.state == RESPAWNST_MOVE)
|
||||
|| mobj->player->respawn.state == RESPAWNST_MOVE
|
||||
|| mobj->player->loop.radius != 0)
|
||||
{
|
||||
P_HitSpecialLines(mobj, mobj->x, mobj->y, mobj->momx, mobj->momy);
|
||||
P_UnsetThingPosition(mobj);
|
||||
|
|
|
|||
|
|
@ -4227,6 +4227,11 @@ void P_PlayerThink(player_t *player)
|
|||
P_DoZoomTube(player);
|
||||
player->rmomx = player->rmomy = 0;
|
||||
}
|
||||
else if (player->loop.radius != 0)
|
||||
{
|
||||
P_PlayerOrbit(player);
|
||||
player->rmomx = player->rmomy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move around.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue