mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
202 lines
5.6 KiB
C
202 lines
5.6 KiB
C
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2025 by "Lat'"
|
|
// Copyright (C) 2025 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 dlzrocket.c
|
|
/// \brief Dead Line Zone free flight rockets! They cool af doe.
|
|
|
|
#include "../doomdef.h"
|
|
#include "../doomstat.h"
|
|
#include "../info.h"
|
|
#include "../k_kart.h"
|
|
#include "../k_objects.h"
|
|
#include "../m_random.h"
|
|
#include "../p_local.h"
|
|
#include "../r_main.h"
|
|
#include "../s_sound.h"
|
|
#include "../g_game.h"
|
|
#include "../z_zone.h"
|
|
#include "../k_waypoint.h"
|
|
#include "../k_respawn.h"
|
|
#include "../k_collide.h"
|
|
#include "../k_color.h"
|
|
|
|
#define DLZROCKETDIST 96
|
|
#define DLZROCKETSPEED 80
|
|
#define DLZROCKETTURNSPEED ((ANG1*3)/2)
|
|
#define DLZROCKETVERTSPEED (ANG1)
|
|
#define DLZROCKETMAXVERT (ANG1*60)
|
|
|
|
void Obj_DLZRocketThink(mobj_t *mo)
|
|
{
|
|
UINT8 i;
|
|
angle_t an = mo->angle + ANGLE_90;
|
|
|
|
if (mo->extravalue1)
|
|
return;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
fixed_t x = mo->x + FixedMul(mapobjectscale, DLZROCKETDIST*FINECOSINE(an>>ANGLETOFINESHIFT));
|
|
fixed_t y = mo->y + FixedMul(mapobjectscale, DLZROCKETDIST*FINESINE(an>>ANGLETOFINESHIFT));
|
|
|
|
mobj_t *r = P_SpawnMobj(x, y, mo->z, MT_THOK);
|
|
P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R);
|
|
P_SetScale(r, (mapobjectscale*3)/2);
|
|
r->destscale = (mapobjectscale*3)/2;
|
|
r->angle = mo->spawnpoint->angle*ANG1;
|
|
r->tics = -1;
|
|
|
|
an += ANGLE_180;
|
|
}
|
|
|
|
mo->extravalue1 = 1;
|
|
}
|
|
|
|
void Obj_DLZRocketDismount(player_t *p)
|
|
{
|
|
// we aren't mounted on one.
|
|
if (!p->dlzrocket)
|
|
return;
|
|
|
|
p->dlzrocket = 0;
|
|
K_SpawnMineExplosion(p->mo, p->mo->color, 3);
|
|
S_StartSound(p->mo, sfx_s3k4e);
|
|
}
|
|
|
|
// touching the rocket, initialize player vars etc...
|
|
void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p)
|
|
{
|
|
if (K_isPlayerInSpecialState(p)) // already on one, don't bother resetting, duh.
|
|
return;
|
|
|
|
p->mo->z = mo->z + 16*P_MobjFlip(p->mo)*mapobjectscale;
|
|
P_SetPlayerAngle(p->mo->player, mo->angle);
|
|
p->dlzrocket = 1;
|
|
p->dlzrocketangle = mo->angle;
|
|
p->dlzrocketanglev = 0;
|
|
p->dlzrocketspd = DLZROCKETSPEED;
|
|
|
|
p->spinouttimer = 0;
|
|
p->wipeoutslow = 0;
|
|
|
|
S_StartSound(mo, sfx_s262);
|
|
}
|
|
|
|
void Obj_playerDLZRocket(player_t *p)
|
|
{
|
|
|
|
fixed_t maxspd = DLZROCKETSPEED;
|
|
angle_t visangle;
|
|
UINT8 i, j;
|
|
|
|
p->dlzrocket++;
|
|
|
|
// helper arrows at the start of the ride to tell players they can move freely
|
|
if (p->dlzrocket < TICRATE*2
|
|
&& leveltime%10 < 5)
|
|
{
|
|
mobj_t *arr = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK);
|
|
arr->sprite = SPR_DLZA;
|
|
arr->frame = FF_FULLBRIGHT;
|
|
P_SetScale(arr, 2*mapobjectscale);
|
|
arr->tics = 2;
|
|
}
|
|
|
|
// calc max speed
|
|
if (p->ringboost)
|
|
maxspd += 10;
|
|
|
|
if (p->startboost)
|
|
maxspd += 30;
|
|
|
|
// set player speed
|
|
if (p->dlzrocketspd < maxspd)
|
|
p->dlzrocketspd++;
|
|
else if (p->dlzrocketspd > maxspd)
|
|
p->dlzrocketspd--;
|
|
|
|
// so long as PF_STASIS is applied, let the angle be overwritten freely.
|
|
// this is used by seasaws but can be used for misc modding purposes too.
|
|
if (p->pflags & PF_STASIS)
|
|
p->dlzrocketangle = p->mo->angle;
|
|
else
|
|
{
|
|
SINT8 turndir = 0;
|
|
P_SetPlayerAngle(p->mo->player, p->dlzrocketangle);
|
|
|
|
if (p->cmd.turning > 0)
|
|
turndir = 1;
|
|
else if (p->cmd.turning < 0)
|
|
turndir = -1;
|
|
|
|
p->dlzrocketangle += turndir*DLZROCKETTURNSPEED;
|
|
|
|
if (p->cmd.throwdir > 0)
|
|
p->dlzrocketanglev = min(DLZROCKETMAXVERT, p->dlzrocketanglev + DLZROCKETVERTSPEED);
|
|
else if (p->cmd.throwdir < 0)
|
|
p->dlzrocketanglev = max(-DLZROCKETMAXVERT, p->dlzrocketanglev - DLZROCKETVERTSPEED);
|
|
|
|
}
|
|
|
|
// angle correction on ceilings (THIS CODE LOOKS AWFUL AND IT CAN PROBABLY BE DONE BETTER......)
|
|
if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && (p->mo->z+p->mo->height >= p->mo->ceilingz))
|
|
|| (p->mo->eflags & MFE_VERTICALFLIP && p->mo->z <= p->mo->floorz))
|
|
if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && p->dlzrocketanglev > 0)
|
|
|| (p->mo->eflags & MFE_VERTICALFLIP && p->dlzrocketanglev < 0))
|
|
p->dlzrocketanglev = 0;
|
|
|
|
|
|
if (!(p->pflags & PF_STASIS))
|
|
{
|
|
angle_t van = p->dlzrocketanglev /4;
|
|
P_InstaThrust(p->mo, p->dlzrocketangle, FixedMul(mapobjectscale, p->dlzrocketspd*FINECOSINE(van>>ANGLETOFINESHIFT)));
|
|
p->mo->momz = FixedMul(mapobjectscale, p->dlzrocketspd*FINESINE((angle_t)p->dlzrocketanglev>>ANGLETOFINESHIFT));
|
|
}
|
|
|
|
if (leveltime%4 == 0)
|
|
S_StartSound(p->mo, sfx_s1c8);
|
|
|
|
// finally, visuals.
|
|
visangle = p->mo->angle + ANGLE_90;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
fixed_t x = p->mo->x + FixedMul(mapobjectscale, 56*FINECOSINE(visangle>>ANGLETOFINESHIFT));
|
|
fixed_t y = p->mo->y + FixedMul(mapobjectscale, 56*FINESINE(visangle>>ANGLETOFINESHIFT));
|
|
mobj_t *r = P_SpawnMobj(x, y, p->mo->z + 16*mapobjectscale, MT_THOK);
|
|
r->fuse = 2;
|
|
P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R);
|
|
P_SetScale(r, (mapobjectscale*3)/2);
|
|
r->angle = p->mo->angle;
|
|
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
fixed_t xoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale;
|
|
fixed_t yoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale;
|
|
fixed_t soffs = P_RandomRange(PR_EXPLOSION, 0, 3);
|
|
|
|
mobj_t *expl = P_SpawnMobj(r->x + xoffs, r->y + yoffs, r->z + xoffs, MT_THOK);
|
|
P_SetMobjState(expl, S_QUICKBOOM1+soffs);
|
|
expl->color = p->mo->color;
|
|
P_SetScale(expl, mapobjectscale);
|
|
expl->destscale = 2*mapobjectscale;
|
|
|
|
if (p->startboost)
|
|
expl->color = K_RainbowColor(leveltime);
|
|
|
|
|
|
}
|
|
visangle += ANGLE_180;
|
|
}
|
|
|
|
if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL))
|
|
|| p->spinouttimer || p->wipeoutslow || p->tumbleBounces
|
|
|| p->respawn.state != RESPAWNST_NONE)
|
|
Obj_DLZRocketDismount(p);
|
|
}
|