Merge branch 'trick-panels-changes' into 'master'

Trick panels changes: Delay + Upwards Trick

See merge request KartKrew/Kart!425
This commit is contained in:
SteelT 2021-06-12 01:33:30 -04:00
commit e1c52c6c61
12 changed files with 293 additions and 20 deletions

View file

@ -232,6 +232,9 @@ typedef enum
khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics
khud_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
// Tricks
khud_trickcool,
NUMKARTHUD
} karthudtype_t;
@ -241,6 +244,7 @@ typedef enum
// CONSTANTS FOR TRICK PANELS
#define TRICKMOMZRAMP (30)
#define TRICKLAG (9)
#define TRICKDELAY (TICRATE/4)
#define TUMBLEBOUNCES 3
@ -450,9 +454,14 @@ typedef struct player_s
UINT8 jawztargetdelay; // (0 to 5) - Delay for Jawz target switching, to make it less twitchy
UINT8 trickpanel; // Trick panel state
UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold
fixed_t trickmomx;
fixed_t trickmomy;
fixed_t trickmomz;
fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks.
UINT8 trickboostdecay; // used to know how long you've waited
UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god.
UINT32 roundscore; // battle score this round
UINT8 emeralds;

View file

@ -748,6 +748,8 @@ char sprnames[NUMSPRITES + 1][5] =
"SDDS", // Spindash dust
"SDWN", // Spindash wind
"TRCK",
"FLBM",
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later

View file

@ -1290,6 +1290,8 @@ typedef enum sprite
SPR_SDDS, // Spindash dust
SPR_SDWN, // Spindash wind
SPR_TRCK,
SPR_FLBM, // Finish line beam
// First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later

View file

@ -162,6 +162,8 @@ static patch_t *kp_cpu;
static patch_t *kp_nametagstem;
static patch_t *kp_trickcool[2];
void K_LoadKartHUDGraphics(void)
{
INT32 i, j;
@ -601,6 +603,9 @@ void K_LoadKartHUDGraphics(void)
kp_cpu = (patch_t *) W_CachePatchName("K_CPU", PU_HUDGFX);
kp_nametagstem = (patch_t *) W_CachePatchName("K_NAMEST", PU_HUDGFX);
kp_trickcool[0] = W_CachePatchName("K_COOL1", PU_HUDGFX);
kp_trickcool[1] = W_CachePatchName("K_COOL2", PU_HUDGFX);
}
// For the item toggle menu
@ -679,6 +684,9 @@ INT32 ITEM2_X, ITEM2_Y;
INT32 LAPS2_X, LAPS2_Y;
INT32 POSI2_X, POSI2_Y;
// trick "cool"
INT32 TCOOL_X, TCOOL_Y;
void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 dupy)
{
@ -982,6 +990,10 @@ static void K_initKartHUD(void)
WANT_X = BASEVIDWIDTH - 55; // 270
WANT_Y = BASEVIDHEIGHT- 71; // 176
// trick COOL
TCOOL_X = (BASEVIDWIDTH)/2;
TCOOL_Y = (BASEVIDHEIGHT)/2 -10;
if (r_splitscreen) // Splitscreen
{
ITEM_X = 5;
@ -1024,6 +1036,8 @@ static void K_initKartHUD(void)
MINI_X = (3*BASEVIDWIDTH/4);
MINI_Y = (3*BASEVIDHEIGHT/4);
TCOOL_X = (BASEVIDWIDTH)/4;
if (r_splitscreen > 2) // 4P-only
{
MINI_X = (BASEVIDWIDTH/2);
@ -3951,6 +3965,32 @@ static void K_drawLapStartAnim(void)
}
}
// stretch for "COOOOOL" popup.
// I can't be fucked to find out any math behind this so have a table lmao
static fixed_t stretch[6][2] = {
{FRACUNIT/4, FRACUNIT*4},
{FRACUNIT/2, FRACUNIT*2},
{FRACUNIT, FRACUNIT},
{FRACUNIT*4, FRACUNIT/2},
{FRACUNIT*8, FRACUNIT/4},
{FRACUNIT*4, FRACUNIT/2},
};
static void K_drawTrickCool(void)
{
tic_t timer = TICRATE - stplyr->karthud[khud_trickcool];
if (timer <= 6)
{
V_DrawStretchyFixedPatch(TCOOL_X<<FRACBITS, TCOOL_Y<<FRACBITS, stretch[timer-1][0], stretch[timer-1][1], V_HUDTRANS|V_SPLITSCREEN, kp_trickcool[splitscreen ? 1 : 0], NULL);
}
else if (leveltime & 1)
{
V_DrawFixedPatch(TCOOL_X<<FRACBITS, (TCOOL_Y<<FRACBITS) - (timer-10)*FRACUNIT/2, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_trickcool[splitscreen ? 1 : 0], NULL);
}
}
void K_drawKartFreePlay(void)
{
// no splitscreen support because it's not FREE PLAY if you have more than one player in-game
@ -4315,6 +4355,10 @@ void K_drawKartHUD(void)
K_drawLapStartAnim();
}
// trick panel cool trick
if (stplyr->karthud[khud_trickcool])
K_drawTrickCool();
if (modeattacking || freecam) // everything after here is MP and debug only
return;

View file

@ -2672,6 +2672,11 @@ static void K_GetKartBoostPower(player_t *player)
}
}
if (player->trickboost) // Trick pannel up-boost
{
ADDBOOST(player->trickboostpower, 5*FRACUNIT, 0); // <trickboostpower>% speed, 500% accel, 0% handling
}
if (player->ringboost) // Ring Boost
{
ADDBOOST(FRACUNIT/5, 4*FRACUNIT, 0); // + 20% top speed, + 400% acceleration, +0% handling
@ -4994,7 +4999,10 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound)
thrust = FixedMul(thrust, 9*FRACUNIT/8);
}
mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = 0; // Reset post-hitlag momentums.
mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer
// Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25)
mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100;
//CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT);
}
mo->momz = FixedMul(thrust, vscale);
@ -6217,6 +6225,9 @@ void K_KartPlayerHUDUpdate(player_t *player)
if (player->karthud[khud_tauntvoices])
player->karthud[khud_tauntvoices]--;
if (player->karthud[khud_trickcool])
player->karthud[khud_trickcool]--;
if (!(player->pflags & PF_FAULT))
player->karthud[khud_fault] = 0;
else if (player->karthud[khud_fault] > 0 && player->karthud[khud_fault] < 2*TICRATE)
@ -6410,7 +6421,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Speed lines
if (player->sneakertimer || player->ringboost
|| player->driftboost || player->startboost
|| player->eggmanexplode)
|| player->eggmanexplode || player->trickboost)
{
if (player->invincibilitytimer)
K_SpawnInvincibilitySpeedLines(player->mo);
@ -6651,6 +6662,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
}
}
if (player->trickboost)
player->trickboost--;
if (player->flamedash)
player->flamedash--;
@ -7394,9 +7408,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
return 0;
}
if (player->trickpanel != 0)
if (player->trickpanel != 0 && player->trickpanel < 4)
{
// No turning during trick panel
// No turning during trick panel unless you did the upwards trick (4)
return 0;
}
@ -8255,6 +8269,86 @@ void K_AdjustPlayerFriction(player_t *player)
}
}
//
// K_trickPanelTimingVisual
// Spawns the timing visual for trick panels depending on the given player's momz.
// If the player has tricked and is not in hitlag, this will send the half circles flying out.
// if you tumble, they'll fall off instead.
//
#define RADIUSSCALING 6
#define MINRADIUS 12
static void K_trickPanelTimingVisual(player_t *player, fixed_t momz)
{
fixed_t pos, tx, ty, tz;
mobj_t *flame;
angle_t hang = R_PointToAnglePlayer(player, player->mo->x, player->mo->y) + ANG1*90; // horizontal angle
angle_t vang = -FixedAngle(momz)*12 + (ANG1*45); // vertical angle dependant on momz, we want it to line up at 45 degrees at the perfect frame to trick at
fixed_t dist = FixedMul(max(MINRADIUS<<FRACBITS, abs(momz)*RADIUSSCALING), player->mo->scale); // distance.
UINT8 i;
// Do you like trig? cool, me neither.
for (i=0; i < 2; i++)
{
pos = FixedMul(dist, FINESINE(vang>>ANGLETOFINESHIFT));
tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT));
ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT));
tz = player->mo->z + player->mo->height/2 + FixedMul(dist, FINECOSINE(vang>>ANGLETOFINESHIFT));
// All coordinates set, spawn our fire, now.
flame = P_SpawnMobj(tx, ty, tz, MT_THOK);
P_SetScale(flame, player->mo->scale);
// Visuals
flame->sprite = SPR_TRCK;
flame->frame = i|FF_FULLBRIGHT;
if (player->trickpanel <= 1 && !player->tumbleBounces)
flame->tics = 2;
else
{
flame->tics = TICRATE;
if (player->trickpanel > 1) // we tricked
{
// Send the thing outwards via ghetto maths which involves redoing the whole 3d sphere again, witht the "vertical" angle shifted by 90 degrees.
// There's probably a simplier way to do this the way I want to but this works.
pos = FixedMul(48*player->mo->scale, FINESINE((vang +ANG1*90)>>ANGLETOFINESHIFT));
tx = player->mo->x + FixedMul(pos, FINECOSINE(hang>>ANGLETOFINESHIFT));
ty = player->mo->y + FixedMul(pos, FINESINE(hang>>ANGLETOFINESHIFT));
tz = player->mo->z + player->mo->height/2 + FixedMul(48*player->mo->scale, FINECOSINE((vang +ANG1*90)>>ANGLETOFINESHIFT));
flame->momx = tx -player->mo->x;
flame->momy = ty -player->mo->y;
flame->momz = tz -(player->mo->z+player->mo->height/2);
}
else // we failed the trick, drop the half circles, it'll be funny I promise.
{
flame->flags &= ~MF_NOGRAVITY;
P_SetObjectMomZ(flame, 4<<FRACBITS, false);
P_InstaThrust(flame, R_PointToAngle2(player->mo->x, player->mo->y, flame->x, flame->y), 8*mapobjectscale);
flame->momx += player->mo->momx;
flame->momy += player->mo->momy;
flame->momz += player->mo->momz;
}
}
// make sure this is only drawn for our local player
flame->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player));
vang += FixedAngle(180<<FRACBITS); // Avoid overflow warnings...
}
}
#undef RADIUSSCALING
#undef MINRADIUS
//
// K_MoveKartPlayer
//
@ -8918,6 +9012,43 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
fixed_t basespeed = P_AproxDistance(player->mo->momx, player->mo->momy); // at WORSE, keep your normal speed when tricking.
fixed_t speed = FixedMul(speedmult, P_AproxDistance(player->mo->momx, player->mo->momy));
K_trickPanelTimingVisual(player, momz);
// streaks:
if (momz*P_MobjFlip(player->mo) > 0) // only spawn those while you're going upwards relative to your current gravity
{
// these are all admittedly arbitrary numbers...
INT32 n;
INT32 maxlines = max(1, (momz/FRACUNIT)/16);
INT32 frequency = max(1, 5-(momz/FRACUNIT)/4);
fixed_t sx, sy, sz;
mobj_t *spdl;
if (!(leveltime % frequency))
{
for (n=0; n < maxlines; n++)
{
sx = player->mo->x + P_RandomRange(-24, 24)*player->mo->scale;
sy = player->mo->y + P_RandomRange(-24, 24)*player->mo->scale;
sz = player->mo->z + P_RandomRange(0, 48)*player->mo->scale;
spdl = P_SpawnMobj(sx, sy, sz, MT_FASTLINE);
P_SetTarget(&spdl->target, player->mo);
spdl->angle = R_PointToAngle2(spdl->x, spdl->y, player->mo->x, player->mo->y);
spdl->rollangle = -ANG1*90*P_MobjFlip(player->mo); // angle them downwards relative to the player's gravity...
spdl->spriteyscale = player->trickboostpower+FRACUNIT;
spdl->momx = player->mo->momx;
spdl->momy = player->mo->momy;
}
}
}
// We'll never need to go above that.
if (player->tricktime <= TRICKDELAY)
player->tricktime++;
// debug shit
//CONS_Printf("%d\n", player->mo->momz / mapobjectscale);
if (momz < -10*FRACUNIT) // :youfuckedup:
@ -8927,11 +9058,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->pflags &= ~PF_TUMBLESOUND;
player->tumbleHeight = 30; // Base tumble bounce height
player->trickpanel = 0;
K_trickPanelTimingVisual(player, momz); // fail trick visual
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
}
else if (!(player->pflags & PF_TRICKDELAY)) // don't allow tricking at the same frame you tumble obv
{
// "COOL" timing n shit.
if (cmd->turning || player->throwdir)
{
if (abs(momz) < FRACUNIT*99) // Let's use that as baseline for PERFECT trick.
{
player->karthud[khud_trickcool] = TICRATE;
}
}
// Uses cmd->turning over steering intentionally.
if (cmd->turning > 0)
{
@ -8945,6 +9087,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (cmd->turning < 0)
{
@ -8958,6 +9101,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->trickpanel = 3;
player->mo->hitlag = TRICKLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == 1)
{
@ -8976,6 +9120,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->trickpanel = 2;
player->mo->hitlag = TRICKLAG;
K_trickPanelTimingVisual(player, momz);
}
else if (player->throwdir == -1)
{
@ -8989,6 +9134,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
relative = false;
}
// Calculate speed boost decay:
// Base speed boost duration is 35 tics.
// At most, lose 3/4th of your boost.
player->trickboostdecay = min(TICRATE*3/4, abs(momz/FRACUNIT));
//CONS_Printf("decay: %d\n", player->trickboostdecay);
P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative);
player->trickmomx = player->mo->momx;
@ -8997,8 +9148,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :)
player->mo->momz = 0;
player->trickpanel = 3;
player->trickpanel = 4;
player->mo->hitlag = TRICKLAG;
K_trickPanelTimingVisual(player, momz);
}
}
}
@ -9013,8 +9165,19 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed!
{
//CONS_Printf("apply boost\n");
S_StartSound(player->mo, sfx_s23c);
K_SpawnDashDustRelease(player);
player->trickboost = TICRATE - player->trickboostdecay;
player->trickpanel = player->trickboostdecay = 0;
}
// Wait until we let go off the control stick to remove the delay
if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning)
// buttons must be neutral after the initial trick delay. This prevents weirdness where slight nudges after blast off would send you flying.
if ((player->pflags & PF_TRICKDELAY) && !player->throwdir && !cmd->turning && (player->tricktime >= TRICKDELAY))
{
player->pflags &= ~PF_TRICKDELAY;
}

View file

@ -2098,6 +2098,16 @@ static int lib_rPointToAngle(lua_State *L)
return 1;
}
static int lib_rPointToAnglePlayer(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
//HUDSAFE
lua_pushangle(L, R_PointToAnglePlayer(player, x, y));
return 1;
}
static int lib_rPointToAngle2(lua_State *L)
{
fixed_t px2 = luaL_checkfixed(L, 1);
@ -3874,6 +3884,7 @@ static luaL_Reg lib[] = {
// r_defs
{"R_PointToAngle",lib_rPointToAngle},
{"R_PointToAnglePlayer", lib_rPointToAnglePlayer},
{"R_PointToAngle2",lib_rPointToAngle2},
{"R_PointToDist",lib_rPointToDist},
{"R_PointToDist2",lib_rPointToDist2},

View file

@ -354,12 +354,20 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->glanceDir);
else if (fastcmp(field,"trickpanel"))
lua_pushinteger(L, plr->trickpanel);
else if (fastcmp(field,"tricktime"))
lua_pushinteger(L, plr->tricktime);
else if (fastcmp(field,"trickmomx"))
lua_pushfixed(L, plr->trickmomx);
else if (fastcmp(field,"trickmomy"))
lua_pushfixed(L, plr->trickmomy);
else if (fastcmp(field,"trickmomz"))
lua_pushfixed(L, plr->trickmomz);
else if (fastcmp(field,"trickboostpower"))
lua_pushfixed(L, plr->trickboostpower);
else if (fastcmp(field,"trickboostdecay"))
lua_pushinteger(L, plr->trickboostdecay);
else if (fastcmp(field,"trickboost"))
lua_pushinteger(L, plr->trickboost);
else if (fastcmp(field,"roundscore"))
plr->roundscore = luaL_checkinteger(L, 3);
else if (fastcmp(field,"emeralds"))
@ -697,12 +705,20 @@ static int player_set(lua_State *L)
plr->glanceDir = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickpanel"))
plr->trickpanel = luaL_checkinteger(L, 3);
else if (fastcmp(field,"tricktime"))
plr->tricktime = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickmomx"))
plr->trickmomx = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomy"))
plr->trickmomy = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickmomz"))
plr->trickmomz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostpower"))
plr->trickboostpower = luaL_checkfixed(L, 3);
else if (fastcmp(field,"trickboostdecay"))
plr->trickboostdecay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"trickboost"))
plr->trickboost = luaL_checkinteger(L, 3);
else if (fastcmp(field,"roundscore"))
lua_pushinteger(L, plr->roundscore);
else if (fastcmp(field,"emeralds"))

View file

@ -1109,7 +1109,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
gravityadd = (4*gravityadd)/3;
}
if (mo->player->trickpanel == 2 || mo->player->trickpanel == 3)
if (mo->player->trickpanel >= 2)
{
gravityadd = (5*gravityadd)/2;
}

View file

@ -305,9 +305,13 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].jawztargetdelay);
WRITEUINT8(save_p, players[i].trickpanel);
WRITEUINT8(save_p, players[i].tricktime);
WRITEUINT32(save_p, players[i].trickmomx);
WRITEUINT32(save_p, players[i].trickmomy);
WRITEUINT32(save_p, players[i].trickmomz);
WRITEUINT32(save_p, players[i].trickboostpower);
WRITEUINT8(save_p, players[i].trickboostdecay);
WRITEUINT8(save_p, players[i].trickboost);
WRITEUINT32(save_p, players[i].roundscore);
WRITEUINT8(save_p, players[i].emeralds);
@ -557,9 +561,13 @@ static void P_NetUnArchivePlayers(void)
players[i].jawztargetdelay = READUINT8(save_p);
players[i].trickpanel = READUINT8(save_p);
players[i].tricktime = READUINT8(save_p);
players[i].trickmomx = READUINT32(save_p);
players[i].trickmomy = READUINT32(save_p);
players[i].trickmomz = READUINT32(save_p);
players[i].trickboostpower = READUINT32(save_p);
players[i].trickboostdecay = READUINT8(save_p);
players[i].trickboost = READUINT8(save_p);
players[i].roundscore = READUINT32(save_p);
players[i].emeralds = READUINT8(save_p);

View file

@ -2040,7 +2040,7 @@ void P_MovePlayer(player_t *player)
{
player->drawangle += ANGLE_22h;
}
else if (player->trickpanel == 3)
else if (player->trickpanel >= 3)
{
player->drawangle -= ANGLE_22h;
}

View file

@ -318,18 +318,35 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line)
angle_t R_PointToAngle(fixed_t x, fixed_t y)
{
return (y -= viewy, (x -= viewx) || y) ?
x >= 0 ?
y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1
x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7
y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3
ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0;
return R_PointToAngle2(viewx, viewy, x, y);
}
// Similar to R_PointToAngle, but requires an additional player_t argument.
// If this player is a local displayplayer, this will base off the calculations off of their camera instead, otherwise use viewx/viewy as usual.
// Yes this is kinda ghetto.
angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y)
{
fixed_t refx = viewx, refy = viewy;
camera_t *cam = NULL;
UINT8 i;
for (i = 0; i < r_splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
cam = &camera[i];
break;
}
}
// use whatever cam we found's coordinates.
if (cam != NULL)
{
refx = cam->x;
refy = cam->y;
}
return R_PointToAngle2(refx, refy, x, y);
}
// This version uses 64-bit variables to avoid overflows with large values.

View file

@ -63,6 +63,7 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node);
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line);
angle_t R_PointToAngle(fixed_t x, fixed_t y);
angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y);
angle_t R_PointToAngle64(INT64 x, INT64 y);
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1);