DLZ rocket hardcode

This commit is contained in:
Lat 2023-09-21 15:42:10 +02:00
parent 02409c5540
commit fb91a9a0f7
9 changed files with 226 additions and 13 deletions

View file

@ -744,9 +744,9 @@ struct player_t
tic_t lasthover; // used for the hover mobjs
// rockets
boolean dlzrocket; // true if latched onto a dlz rocket.
tic_t dlzrocket; // counts up as we stay on a rocket.
angle_t dlzrocketangle; // current travel angle with the rocket.
angle_t dlzrocketanglev; // current vertical travel angle with the rocket.
INT32 dlzrocketanglev; // current vertical travel angle with the rocket. signed instead of angle_t.
fixed_t dlzrocketspd; // current rocket travel speed.
// seasaws (variables are shared with other seasaw-like objects)

View file

@ -11845,6 +11845,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->bungee)
Obj_playerBungeeThink(player);
if (player->dlzrocket)
Obj_playerDLZRocket(player);
}
void K_CheckSpectateStatus(boolean considermapreset)

View file

@ -247,6 +247,12 @@ void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee
void Obj_EggBallSpawnerThink(mobj_t *mo);
void Obj_EggBallThink(mobj_t *mo);
/* DLZ Rockets */
void Obj_DLZRocketSpawn(mobj_t *mo);
void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p); // touch activation
void Obj_playerDLZRocket(player_t *p); // player looping thinker
void Obj_DLZRocketDismount(player_t *p); // used in p_map.c to get off the rocket when we cross transfer lines.
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -32,5 +32,6 @@ target_sources(SRB2SDL2 PRIVATE
rideroid.c
bungee.c
eggball.c
dlzrocket.c
shadow.cpp
)

190
src/objects/dlzrocket.c Normal file
View file

@ -0,0 +1,190 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2022 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"
#define DLZROCKETDIST 96
#define DLZROCKETSPEED 80
#define DLZROCKETTURNSPEED ((ANG1*3)/2)
#define DLZROCKETVERTSPEED (ANG1)
#define DLZROCKETMAXVERT (ANG1*60)
void Obj_DLZRocketSpawn(mobj_t *mo)
{
UINT8 i;
angle_t an = mo->angle + ANGLE_90;
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->angle = mo->angle;
r->tics = -1;
an += ANGLE_180;
}
}
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 (p->dlzrocket) // 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 = true;
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;
// set player speed
if (p->dlzrocketspd < maxspd)
p->dlzrocketspd++;
else if (p->dlzrocketspd > maxspd)
p->dlzrocket--;
// 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_FUZZ, -6, 6)*mapobjectscale;
fixed_t yoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale;
fixed_t soffs = P_RandomRange(PR_FUZZ, 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;
}
visangle += ANGLE_180;
}
if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL))
|| p->spinouttimer || p->wipeoutslow || p->tumbleHeight)
Obj_DLZRocketDismount(p);
}

View file

@ -820,7 +820,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_RAINBOWDASHRING:
Obj_DashRingTouch(special, player);
return;
case MT_DLZ_ROCKET:
Obj_DLZRocketSpecial(special, player);
return;
default: // SOC or script pickup
P_SetTarget(&special->target, toucher);
break;

View file

@ -1879,10 +1879,16 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld)
}
// a bit of a hacky behaviour, but not that I know where else it would go.
if (tm.thing->type == MT_RIDEROID
&& tm.blockingline->flags & ML_TFERLINE)
if (tm.blockingline->flags & ML_TFERLINE)
{
Obj_getPlayerOffRideroid(tm.thing);
if (tm.thing->type == MT_RIDEROID)
{
Obj_getPlayerOffRideroid(tm.thing);
}
else if (tm.thing->type == MT_PLAYER && tm.thing->player && tm.thing->player->dlzrocket)
{
Obj_DLZRocketDismount(tm.thing->player);
}
}
if (!ld->backsector) // one sided line

View file

@ -11160,7 +11160,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_RIDEROIDNODE:
Obj_RideroidNodeSpawn(mobj);
break;
break;
case MT_DLZ_ROCKET:
Obj_DLZRocketSpawn(mobj);
break;
case MT_SNEAKERPANEL:
Obj_SneakerPanelSpawn(mobj);
break;

View file

@ -567,9 +567,9 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT32(save->p, players[i].lasthover);
WRITEUINT8(save->p, players[i].dlzrocket);
WRITEUINT32(save->p, players[i].dlzrocketangle);
WRITEUINT32(save->p, players[i].dlzrocketanglev);
WRITEUINT32(save->p, players[i].dlzrocket);
WRITEANGLE(save->p, players[i].dlzrocketangle);
WRITEINT32(save->p, players[i].dlzrocketanglev);
WRITEUINT32(save->p, players[i].dlzrocketspd);
WRITEUINT8(save->p, players[i].seasaw);
@ -1068,9 +1068,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].lasthover = READUINT32(save->p);
players[i].dlzrocket = READUINT8(save->p);
players[i].dlzrocketangle = READUINT32(save->p);
players[i].dlzrocketanglev = READUINT32(save->p);
players[i].dlzrocket = READUINT32(save->p);
players[i].dlzrocketangle = READANGLE(save->p);
players[i].dlzrocketanglev = READINT32(save->p);
players[i].dlzrocketspd = READUINT32(save->p);
players[i].seasaw = READUINT8(save->p);