mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-11 01:02:16 +00:00
Huge respawn overhaul
- Moved respawn code to its own file - Reorganized a lot of the code related to respawning - As a result of the massive reorganization, I squashed several bugs. Most notably: mid-game joiners having weird spawns, being able to skip laps by respawning. - Respawn lightsnake no longer takes you straight to your nextwaypoint -- it now has a minimum distance forward that it tries to put you at when you respawn.
This commit is contained in:
parent
e18d71d562
commit
d062a35a3a
23 changed files with 918 additions and 561 deletions
|
|
@ -165,6 +165,7 @@ set(SRB2_CORE_GAME_SOURCES
|
|||
k_pwrlv.c
|
||||
k_waypoint.c
|
||||
k_color.c
|
||||
k_respawn.c
|
||||
|
||||
p_local.h
|
||||
p_maputl.h
|
||||
|
|
@ -184,6 +185,7 @@ set(SRB2_CORE_GAME_SOURCES
|
|||
k_pwrlv.h
|
||||
k_waypoint.h
|
||||
k_color.h
|
||||
k_respawn.h
|
||||
)
|
||||
|
||||
if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
||||
|
|
|
|||
|
|
@ -506,6 +506,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/y_inter.o \
|
||||
$(OBJDIR)/st_stuff.o \
|
||||
$(OBJDIR)/k_kart.o \
|
||||
$(OBJDIR)/k_respawn.o\
|
||||
$(OBJDIR)/k_collide.o\
|
||||
$(OBJDIR)/k_color.o \
|
||||
$(OBJDIR)/k_battle.o \
|
||||
|
|
|
|||
|
|
@ -611,12 +611,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
|||
rsp->weapondelay = LONG(players[i].weapondelay);
|
||||
rsp->tossdelay = LONG(players[i].tossdelay);
|
||||
|
||||
rsp->starpostx = SHORT(players[i].starpostx);
|
||||
rsp->starposty = SHORT(players[i].starposty);
|
||||
rsp->starpostz = SHORT(players[i].starpostz);
|
||||
rsp->starpostnum = LONG(players[i].starpostnum);
|
||||
rsp->starposttime = (tic_t)LONG(players[i].starposttime);
|
||||
rsp->starpostangle = (angle_t)LONG(players[i].starpostangle);
|
||||
|
||||
rsp->maxlink = LONG(players[i].maxlink);
|
||||
rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed);
|
||||
|
|
@ -734,12 +729,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].weapondelay = LONG(rsp->weapondelay);
|
||||
players[i].tossdelay = LONG(rsp->tossdelay);
|
||||
|
||||
players[i].starpostx = SHORT(rsp->starpostx);
|
||||
players[i].starposty = SHORT(rsp->starposty);
|
||||
players[i].starpostz = SHORT(rsp->starpostz);
|
||||
players[i].starpostnum = LONG(rsp->starpostnum);
|
||||
players[i].starposttime = (tic_t)LONG(rsp->starposttime);
|
||||
players[i].starpostangle = (angle_t)LONG(rsp->starpostangle);
|
||||
|
||||
players[i].maxlink = LONG(rsp->maxlink);
|
||||
players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed);
|
||||
|
|
|
|||
|
|
@ -252,12 +252,7 @@ typedef struct
|
|||
INT32 weapondelay;
|
||||
INT32 tossdelay;
|
||||
|
||||
INT16 starpostx;
|
||||
INT16 starposty;
|
||||
INT16 starpostz;
|
||||
INT32 starpostnum;
|
||||
tic_t starposttime;
|
||||
angle_t starpostangle;
|
||||
|
||||
INT32 maxlink;
|
||||
fixed_t dashspeed;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "k_pwrlv.h"
|
||||
#include "y_inter.h"
|
||||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
|
|
|||
|
|
@ -264,9 +264,6 @@ typedef enum
|
|||
k_position, // Used for Kart positions, mostly for deterministic stuff
|
||||
k_oldposition, // Used for taunting when you pass someone
|
||||
k_positiondelay, // Used for position number, so it can grow when passing/being passed
|
||||
k_starpostflip, // the last starpost we hit requires flipping?
|
||||
k_respawn, // Timer for the DEZ laser respawn effect
|
||||
k_dropdash, // Charge up for respawn Drop Dash
|
||||
|
||||
k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
|
||||
k_instashield, // Instashield no-damage animation timer
|
||||
|
|
@ -420,6 +417,20 @@ typedef enum
|
|||
RW_RAIL = 32
|
||||
} ringweapons_t;
|
||||
|
||||
// player_t struct for all respawn variables
|
||||
typedef struct respawnvars_s
|
||||
{
|
||||
UINT8 respawnstate; // 0: not respawning, 1: heading towards respawn point, 2: about to drop
|
||||
waypoint_t *wp; // Waypoint that we're going towards, NULL if the position isn't linked to one
|
||||
INT32 pointx; // Respawn position coords to go towards
|
||||
INT32 pointy;
|
||||
INT32 pointz;
|
||||
boolean flip; // Flip upside down or not
|
||||
INT32 timer; // Time left on respawn animation once you're there
|
||||
UINT32 distanceleft; // How far along the course to respawn you
|
||||
INT32 dropdash; // Drop Dash charge timer
|
||||
} respawnvars_t;
|
||||
|
||||
// ========================================================================
|
||||
// PLAYER STRUCTURE
|
||||
// ========================================================================
|
||||
|
|
@ -466,6 +477,7 @@ typedef struct player_s
|
|||
INT16 rturn_max[MAXPREDICTTICS]; // Ditto but for full-right
|
||||
UINT32 distancetofinish;
|
||||
waypoint_t *nextwaypoint;
|
||||
respawnvars_t respawnvars; // SRB2Kart: respawn info
|
||||
|
||||
// Bit flags.
|
||||
// See pflags_t, above.
|
||||
|
|
@ -531,6 +543,7 @@ typedef struct player_s
|
|||
INT16 totalring; // Total number of rings obtained for Race Mode
|
||||
tic_t realtime; // integer replacement for leveltime
|
||||
UINT8 laps; // Number of laps (optional)
|
||||
INT32 starpostnum; // The number of the last starpost you hit
|
||||
|
||||
////////////////////
|
||||
// CTF Mode Stuff //
|
||||
|
|
@ -541,14 +554,6 @@ typedef struct player_s
|
|||
INT32 weapondelay; // Delay (if any) to fire the weapon again
|
||||
INT32 tossdelay; // Delay (if any) to toss a flag/emeralds again
|
||||
|
||||
// Starpost information
|
||||
INT16 starpostx;
|
||||
INT16 starposty;
|
||||
INT16 starpostz;
|
||||
INT32 starpostnum; // The number of the last starpost you hit
|
||||
tic_t starposttime; // Your time when you hit the starpost
|
||||
angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way
|
||||
|
||||
/////////////////
|
||||
// NiGHTS Stuff//
|
||||
/////////////////
|
||||
|
|
|
|||
|
|
@ -8314,9 +8314,6 @@ static const char *const KARTSTUFF_LIST[] = {
|
|||
"POSITION",
|
||||
"OLDPOSITION",
|
||||
"POSITIONDELAY",
|
||||
"STARPOSTFLIP",
|
||||
"RESPAWN",
|
||||
"DROPDASH",
|
||||
|
||||
"THROWDIR",
|
||||
"INSTASHIELD",
|
||||
|
|
|
|||
38
src/g_game.c
38
src/g_game.c
|
|
@ -53,6 +53,7 @@
|
|||
#include "k_battle.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
gameaction_t gameaction;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
|
|
@ -1587,7 +1588,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
// SRB2kart - no additional angle if not moving
|
||||
if ((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (player->kartstuff[k_respawn]) // Respawning
|
||||
|| (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning
|
||||
|| (player->spectator || objectplacing)) // Not a physical player
|
||||
lang += (cmd->angleturn<<16);
|
||||
|
||||
|
|
@ -2536,12 +2537,9 @@ static inline void G_PlayerFinishLevel(INT32 player)
|
|||
|
||||
p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
|
||||
P_FlashPal(p, 0, 0); // Resets
|
||||
p->starpostangle = 0;
|
||||
p->starposttime = 0;
|
||||
p->starpostx = 0;
|
||||
p->starposty = 0;
|
||||
p->starpostz = 0;
|
||||
|
||||
p->starpostnum = 0;
|
||||
memset(&p->respawnvars, 0, sizeof (p->respawnvars));
|
||||
|
||||
// SRB2kart: Increment the "matches played" counter.
|
||||
if (player == consoleplayer)
|
||||
|
|
@ -2575,12 +2573,7 @@ void G_PlayerReborn(INT32 player)
|
|||
INT32 charflags;
|
||||
INT32 pflags;
|
||||
INT32 ctfteam;
|
||||
INT32 starposttime;
|
||||
INT16 starpostx;
|
||||
INT16 starposty;
|
||||
INT16 starpostz;
|
||||
INT32 starpostnum;
|
||||
INT32 starpostangle;
|
||||
INT32 exiting;
|
||||
INT16 numboxes;
|
||||
INT16 totalring;
|
||||
|
|
@ -2604,7 +2597,6 @@ void G_PlayerReborn(INT32 player)
|
|||
INT32 comebackpoints;
|
||||
INT32 wanted;
|
||||
INT32 rings;
|
||||
INT32 respawnflip;
|
||||
boolean songcredit = false;
|
||||
|
||||
score = players[player].score;
|
||||
|
|
@ -2634,13 +2626,7 @@ void G_PlayerReborn(INT32 player)
|
|||
//
|
||||
charflags = players[player].charflags;
|
||||
|
||||
starposttime = players[player].starposttime;
|
||||
starpostx = players[player].starpostx;
|
||||
starposty = players[player].starposty;
|
||||
starpostz = players[player].starpostz;
|
||||
starpostnum = players[player].starpostnum;
|
||||
respawnflip = players[player].kartstuff[k_starpostflip]; //SRB2KART
|
||||
starpostangle = players[player].starpostangle;
|
||||
|
||||
mare = players[player].mare;
|
||||
bot = players[player].bot;
|
||||
|
|
@ -2709,12 +2695,7 @@ void G_PlayerReborn(INT32 player)
|
|||
//
|
||||
p->charflags = charflags;
|
||||
|
||||
p->starposttime = starposttime;
|
||||
p->starpostx = starpostx;
|
||||
p->starposty = starposty;
|
||||
p->starpostz = starpostz;
|
||||
p->starpostnum = starpostnum;
|
||||
p->starpostangle = starpostangle;
|
||||
p->exiting = exiting;
|
||||
|
||||
p->numboxes = numboxes;
|
||||
|
|
@ -2739,7 +2720,6 @@ void G_PlayerReborn(INT32 player)
|
|||
p->kartstuff[k_wanted] = wanted;
|
||||
p->kartstuff[k_eggmanblame] = -1;
|
||||
p->kartstuff[k_lastdraft] = -1;
|
||||
p->kartstuff[k_starpostflip] = respawnflip;
|
||||
|
||||
// Don't do anything immediately
|
||||
p->pflags |= PF_USEDOWN;
|
||||
|
|
@ -2772,7 +2752,9 @@ void G_PlayerReborn(INT32 player)
|
|||
S_ShowMusicCredit();
|
||||
|
||||
if (leveltime > (starttime + (TICRATE/2)) && !p->spectator)
|
||||
p->kartstuff[k_respawn] = 48; // Respawn effect
|
||||
{
|
||||
K_DoIngameRespawn(p);
|
||||
}
|
||||
|
||||
if (gametype == GT_COOP)
|
||||
P_FindEmerald(); // scan for emeralds to hunt for
|
||||
|
|
@ -4680,8 +4662,8 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
|
|||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
players[i].playerstate = PST_REBORN;
|
||||
players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0;
|
||||
players[i].starpostx = players[i].starposty = players[i].starpostz = 0;
|
||||
players[i].starpostnum = 0;
|
||||
memset(&players[i].respawnvars, 0, sizeof (players[i].respawnvars));
|
||||
|
||||
#if 0
|
||||
if (netgame || multiplayer)
|
||||
|
|
@ -5203,7 +5185,7 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
// SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam
|
||||
if (((players[displayplayers[0]].mo && players[displayplayers[0]].speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (players[displayplayers[0]].kartstuff[k_respawn]) // Respawning
|
||||
|| (players[displayplayers[0]].respawnvars.respawnstate != RESPAWNST_NONE) // Respawning
|
||||
|| (players[displayplayers[0]].spectator || objectplacing)) // Not a physical player
|
||||
&& !(players[displayplayers[0]].kartstuff[k_spinouttimer]
|
||||
&& (players[displayplayers[0]].kartstuff[k_sneakertimer] || players[displayplayers[0]].kartstuff[k_levelbooster]))) // Spinning and boosting cancels out spinout
|
||||
|
|
|
|||
411
src/k_kart.c
411
src/k_kart.c
|
|
@ -8,6 +8,7 @@
|
|||
#include "k_battle.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
#include "doomdef.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_game.h"
|
||||
|
|
@ -962,8 +963,8 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
|| (mobj2->player && mobj2->player->playerstate != PST_LIVE))
|
||||
return;
|
||||
|
||||
if ((mobj1->player && mobj1->player->kartstuff[k_respawn])
|
||||
|| (mobj2->player && mobj2->player->kartstuff[k_respawn]))
|
||||
if ((mobj1->player && mobj1->player->respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
|| (mobj2->player && mobj2->player->respawnvars.respawnstate != RESPAWNST_NONE))
|
||||
return;
|
||||
|
||||
{ // Don't bump if you're flashing
|
||||
|
|
@ -1461,7 +1462,6 @@ void K_FlipFromObject(mobj_t *mo, mobj_t *master)
|
|||
mo->z += master->height - FixedMul(master->scale, mo->height);
|
||||
}
|
||||
|
||||
// These have to go earlier than its sisters because of K_RespawnChecker...
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
||||
{
|
||||
// flipping
|
||||
|
|
@ -1476,7 +1476,7 @@ void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
|||
mo->eflags = (mo->eflags & ~MFE_DRAWONLYFORP4)|(master->eflags & MFE_DRAWONLYFORP4);
|
||||
}
|
||||
|
||||
static void K_SpawnDashDustRelease(player_t *player)
|
||||
void K_SpawnDashDustRelease(player_t *player)
|
||||
{
|
||||
fixed_t newx;
|
||||
fixed_t newy;
|
||||
|
|
@ -1535,362 +1535,6 @@ static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the m
|
|||
sparks->flags2 |= MF2_DONTDRAW;
|
||||
}
|
||||
|
||||
/** \brief Preps a player to respawn
|
||||
|
||||
\param player player to respawn
|
||||
|
||||
\return void
|
||||
*/
|
||||
void K_DoIngameRespawn(player_t *player)
|
||||
{
|
||||
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||
return;
|
||||
|
||||
if (player->kartstuff[k_respawn])
|
||||
return;
|
||||
|
||||
if (leveltime <= starttime)
|
||||
return;
|
||||
|
||||
if (player->nextwaypoint == NULL) // Starpost xyz not initalized(?)
|
||||
{
|
||||
UINT32 bestdist = UINT32_MAX;
|
||||
mapthing_t *beststart = NULL;
|
||||
UINT8 numstarts = 0;
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
numstarts = numcoopstarts;
|
||||
}
|
||||
else if (G_BattleGametype())
|
||||
{
|
||||
numstarts = numdmstarts;
|
||||
}
|
||||
|
||||
if (numstarts > 0)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
|
||||
for (i = 0; i < numstarts; i++)
|
||||
{
|
||||
UINT32 dist = UINT32_MAX;
|
||||
mapthing_t *checkstart = NULL;
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
checkstart = playerstarts[i];
|
||||
}
|
||||
else if (G_BattleGametype())
|
||||
{
|
||||
checkstart = deathmatchstarts[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
dist = (UINT32)P_AproxDistance((player->mo->x >> FRACBITS) - checkstart->x,
|
||||
(player->mo->y >> FRACBITS) - checkstart->y);
|
||||
|
||||
if (dist < bestdist)
|
||||
{
|
||||
beststart = checkstart;
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (beststart == NULL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "No respawn points!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sector_t *s;
|
||||
fixed_t z = (beststart->options >> ZSHIFT);
|
||||
|
||||
player->starpostx = beststart->x;
|
||||
player->starposty = beststart->y;
|
||||
s = R_PointInSubsector(beststart->x << FRACBITS, beststart->y << FRACBITS)->sector;
|
||||
|
||||
if (beststart->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
player->starpostz = (
|
||||
#ifdef ESLOPE
|
||||
s->c_slope ? P_GetZAt(s->c_slope, beststart->x << FRACBITS, beststart->y << FRACBITS) :
|
||||
#endif
|
||||
s->ceilingheight) >> FRACBITS;
|
||||
|
||||
if (z)
|
||||
player->starpostz -= z;
|
||||
|
||||
player->starpostz -= mobjinfo[MT_PLAYER].height;
|
||||
player->kartstuff[k_starpostflip] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->starpostz = (
|
||||
#ifdef ESLOPE
|
||||
s->f_slope ? P_GetZAt(s->f_slope, beststart->x << FRACBITS, beststart->y << FRACBITS) :
|
||||
#endif
|
||||
s->floorheight) >> FRACBITS;
|
||||
|
||||
if (z)
|
||||
player->starpostz += z;
|
||||
|
||||
player->kartstuff[k_starpostflip] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player->mo->flags &= ~(MF_SOLID|MF_SHOOTABLE);
|
||||
player->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY;
|
||||
player->mo->flags2 &= ~MF2_DONTDRAW;
|
||||
|
||||
player->kartstuff[k_respawn] = 48;
|
||||
}
|
||||
|
||||
/** \brief Calculates the respawn timer and drop-boosting
|
||||
|
||||
\param player player object passed from K_KartPlayerThink
|
||||
|
||||
\return void
|
||||
*/
|
||||
void K_RespawnChecker(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
if (player->spectator)
|
||||
return;
|
||||
|
||||
if (player->kartstuff[k_respawn] > 1)
|
||||
{
|
||||
fixed_t destx = 0, desty = 0, destz = 0;
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
player->powers[pw_flashing] = 2;
|
||||
player->powers[pw_nocontrol] = 2;
|
||||
|
||||
if (leveltime % 8 == 0 && !mapreset)
|
||||
S_StartSound(player->mo, sfx_s3kcas);
|
||||
|
||||
destx = (player->starpostx << FRACBITS);
|
||||
desty = (player->starposty << FRACBITS);
|
||||
destz = (player->starpostz << FRACBITS);
|
||||
|
||||
if (player->kartstuff[k_starpostflip])
|
||||
{
|
||||
// This variable is set from the settings of the best waypoint, thus this waypoint is FLIPPED as well.
|
||||
// So we should flip the player in advance for it as well.
|
||||
player->mo->flags2 |= MF2_OBJECTFLIP;
|
||||
player->mo->eflags |= MFE_VERTICALFLIP;
|
||||
destz -= (128 * mapobjectscale) + (player->mo->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ditto, but this waypoint isn't flipped, so make sure the player also isn't flipped!
|
||||
player->mo->flags2 &= ~MF2_OBJECTFLIP;
|
||||
player->mo->eflags &= ~MFE_VERTICALFLIP;
|
||||
destz += (128 * mapobjectscale);
|
||||
}
|
||||
|
||||
if (player->mo->x != destx || player->mo->y != desty || player->mo->z != destz)
|
||||
{
|
||||
fixed_t step = 64*mapobjectscale;
|
||||
fixed_t dist = P_AproxDistance(P_AproxDistance(player->mo->x - destx, player->mo->y - desty), player->mo->z - destz);
|
||||
|
||||
if (dist <= step) // You're ready to respawn
|
||||
{
|
||||
P_TryMove(player->mo, destx, desty, true);
|
||||
player->mo->z = destz;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t stepx = 0, stepy = 0, stepz = 0;
|
||||
angle_t stepha = R_PointToAngle2(player->mo->x, player->mo->y, destx, desty);
|
||||
angle_t stepva = R_PointToAngle2(0, player->mo->z, P_AproxDistance(player->mo->x - destx, player->mo->y - desty), destz);
|
||||
fixed_t laserx = 0, lasery = 0, laserz = 0;
|
||||
UINT8 lasersteps = 4;
|
||||
|
||||
// Move toward the respawn point
|
||||
stepx = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
stepy = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
stepz = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*step);
|
||||
|
||||
P_TryMove(player->mo, player->mo->x + stepx, player->mo->y + stepy, true);
|
||||
player->mo->z += stepz;
|
||||
|
||||
// Spawn lasers along the path
|
||||
laserx = player->mo->x + (stepx / 2);
|
||||
lasery = player->mo->y + (stepy / 2);
|
||||
laserz = player->mo->z + (stepz / 2);
|
||||
dist = P_AproxDistance(P_AproxDistance(laserx - destx, lasery - desty), laserz - destz);
|
||||
|
||||
if (dist > step/2)
|
||||
{
|
||||
while (lasersteps)
|
||||
{
|
||||
|
||||
stepha = R_PointToAngle2(laserx, lasery, destx, desty);
|
||||
stepva = R_PointToAngle2(0, laserz, P_AproxDistance(laserx - destx, lasery - desty), destz);
|
||||
|
||||
stepx = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
stepy = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), step), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
stepz = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*step);
|
||||
|
||||
laserx += stepx;
|
||||
lasery += stepy;
|
||||
laserz += stepz;
|
||||
dist = P_AproxDistance(P_AproxDistance(laserx - destx, lasery - desty), laserz - destz);
|
||||
|
||||
if (dist <= step/2)
|
||||
break;
|
||||
|
||||
lasersteps--;
|
||||
}
|
||||
}
|
||||
|
||||
if (lasersteps == 0) // Don't spawn them beyond the respawn point.
|
||||
{
|
||||
mobj_t *laser;
|
||||
|
||||
laser = P_SpawnMobj(laserx, lasery, laserz + (player->mo->height / 2), MT_DEZLASER);
|
||||
|
||||
if (laser && !P_MobjWasRemoved(laser))
|
||||
{
|
||||
P_SetMobjState(laser, S_DEZLASER_TRAIL1);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
laser->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetTarget(&laser->target, player->mo);
|
||||
laser->angle = stepha + ANGLE_90;
|
||||
P_SetScale(laser, (laser->destscale = FRACUNIT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->kartstuff[k_respawn]--;
|
||||
|
||||
player->mo->flags |= MF_SOLID|MF_SHOOTABLE;
|
||||
player->mo->flags &= ~(MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY);
|
||||
if (!(player->pflags & PF_NOCLIP))
|
||||
player->mo->flags &= ~MF_NOCLIP;
|
||||
|
||||
if (leveltime % 8 == 0)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mobj_t *laser;
|
||||
angle_t newangle;
|
||||
fixed_t newx, newy, newz;
|
||||
|
||||
newangle = FixedAngle(((360/8)*i)*FRACUNIT);
|
||||
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
|
||||
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
newz = player->mo->z + player->mo->height;
|
||||
else
|
||||
newz = player->mo->z;
|
||||
|
||||
laser = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
|
||||
|
||||
if (laser && !P_MobjWasRemoved(laser))
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
laser->eflags |= MFE_VERTICALFLIP;
|
||||
P_SetTarget(&laser->target, player->mo);
|
||||
laser->angle = newangle+ANGLE_90;
|
||||
laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
|
||||
P_SetScale(laser, (laser->destscale = player->mo->scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (player->kartstuff[k_respawn] == 1)
|
||||
{
|
||||
if (player->kartstuff[k_growshrinktimer] < 0)
|
||||
{
|
||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||
player->mo->destscale = (6*mapobjectscale)/8;
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
||||
}
|
||||
|
||||
if (!P_IsObjectOnGround(player->mo) && !mapreset)
|
||||
{
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
|
||||
// Sal: The old behavior was stupid and prone to accidental usage.
|
||||
// Let's rip off Mania instead, and turn this into a Drop Dash!
|
||||
|
||||
if (cmd->buttons & BT_ACCELERATE && !player->kartstuff[k_spinouttimer]) // Lat: Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway)
|
||||
player->kartstuff[k_dropdash]++;
|
||||
else
|
||||
player->kartstuff[k_dropdash] = 0;
|
||||
|
||||
if (player->kartstuff[k_dropdash] == TICRATE/4)
|
||||
S_StartSound(player->mo, sfx_ddash);
|
||||
|
||||
if ((player->kartstuff[k_dropdash] >= TICRATE/4)
|
||||
&& (player->kartstuff[k_dropdash] & 1))
|
||||
player->mo->colorized = true;
|
||||
else
|
||||
player->mo->colorized = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((cmd->buttons & BT_ACCELERATE) && (player->kartstuff[k_dropdash] >= TICRATE/4))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s23c);
|
||||
player->kartstuff[k_startboost] = 50;
|
||||
K_SpawnDashDustRelease(player);
|
||||
}
|
||||
|
||||
player->mo->colorized = false;
|
||||
player->kartstuff[k_dropdash] = 0;
|
||||
player->kartstuff[k_respawn] = 0;
|
||||
|
||||
//P_PlayRinglossSound(player->mo);
|
||||
P_PlayerRingBurst(player, 3);
|
||||
|
||||
if (G_BattleGametype())
|
||||
{
|
||||
if (player->kartstuff[k_bumper] > 0)
|
||||
{
|
||||
if (player->kartstuff[k_bumper] == 1)
|
||||
{
|
||||
mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!!
|
||||
P_SetTarget(&karmahitbox->target, player->mo);
|
||||
karmahitbox->destscale = player->mo->scale;
|
||||
P_SetScale(karmahitbox, player->mo->scale);
|
||||
CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]);
|
||||
}
|
||||
player->kartstuff[k_bumper]--;
|
||||
if (K_IsPlayerWanted(player))
|
||||
K_CalculateBattleWanted();
|
||||
}
|
||||
|
||||
if (!player->kartstuff[k_bumper])
|
||||
{
|
||||
player->kartstuff[k_comebacktimer] = comebacktime;
|
||||
if (player->kartstuff[k_comebackmode] == 2)
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE);
|
||||
S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound);
|
||||
player->kartstuff[k_comebackmode] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
K_CheckBumpers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Handles the state changing for moving players, moved here to eliminate duplicate code
|
||||
|
||||
\param player player data
|
||||
|
|
@ -5198,7 +4842,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
|
|||
#endif
|
||||
return;
|
||||
|
||||
if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->kartstuff[k_respawn] == 1)) // Startup boosts
|
||||
if ((leveltime >= starttime-(2*TICRATE) && leveltime <= starttime) || (player->respawnvars.respawnstate == RESPAWNST_DROP)) // Startup boosts
|
||||
targetsnd = ((cmd->buttons & BT_ACCELERATE) ? 12 : 0);
|
||||
else
|
||||
targetsnd = (((6*cmd->forwardmove)/25) + ((player->speed / mapobjectscale)/5))/2;
|
||||
|
|
@ -5599,7 +5243,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here
|
||||
if (player->playerstate == PST_DEAD || (player->respawnvars.respawnstate == RESPAWNST_MOVE)) // Ensure these are set correctly here
|
||||
{
|
||||
player->mo->colorized = false;
|
||||
player->mo->color = player->skincolor;
|
||||
|
|
@ -5775,7 +5419,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (player->kartstuff[k_invincibilitytimer])
|
||||
player->kartstuff[k_invincibilitytimer]--;
|
||||
|
||||
if (!player->kartstuff[k_respawn] && player->kartstuff[k_growshrinktimer] != 0)
|
||||
if ((player->respawnvars.respawnstate == RESPAWNST_NONE) && player->kartstuff[k_growshrinktimer] != 0)
|
||||
{
|
||||
if (player->kartstuff[k_growshrinktimer] > 0)
|
||||
player->kartstuff[k_growshrinktimer]--;
|
||||
|
|
@ -5845,7 +5489,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (G_BattleGametype() && player->kartstuff[k_bumper] > 0
|
||||
&& !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer]
|
||||
&& !player->kartstuff[k_respawn] && !player->powers[pw_flashing])
|
||||
&& (player->respawnvars.respawnstate == RESPAWNST_DROP) && !player->powers[pw_flashing])
|
||||
{
|
||||
player->kartstuff[k_wanted]++;
|
||||
if (battleovertime.enabled >= 10*TICRATE)
|
||||
|
|
@ -5931,10 +5575,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
else
|
||||
player->kartstuff[k_jmp] = 0;
|
||||
|
||||
// Respawn Checker
|
||||
if (player->kartstuff[k_respawn])
|
||||
K_RespawnChecker(player);
|
||||
|
||||
// Roulette Code
|
||||
K_KartItemRoulette(player, cmd);
|
||||
|
||||
|
|
@ -6169,36 +5809,13 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
|
||||
// Respawn point should only be updated when we're going to a nextwaypoint
|
||||
if ((updaterespawn) &&
|
||||
(player->respawnvars.respawnstate == RESPAWNST_NONE) &&
|
||||
(bestwaypoint != NULL) &&
|
||||
(bestwaypoint != player->nextwaypoint) &&
|
||||
(player->kartstuff[k_respawn] == 0) &&
|
||||
(K_GetWaypointIsSpawnpoint(bestwaypoint)) && // Don't try to respawn on waypoints that are marked with no respawn
|
||||
(K_GetWaypointIsShortcut(bestwaypoint) == false) && (K_GetWaypointIsEnabled(bestwaypoint) == true))
|
||||
(K_GetWaypointIsSpawnpoint(bestwaypoint)) &&
|
||||
(K_GetWaypointIsEnabled(bestwaypoint) == true))
|
||||
{
|
||||
size_t i = 0U;
|
||||
waypoint_t *aimwaypoint = NULL;
|
||||
|
||||
player->starpostx = bestwaypoint->mobj->x >> FRACBITS;
|
||||
player->starposty = bestwaypoint->mobj->y >> FRACBITS;
|
||||
player->starpostz = bestwaypoint->mobj->z >> FRACBITS;
|
||||
player->kartstuff[k_starpostflip] = (bestwaypoint->mobj->flags2 & MF2_OBJECTFLIP);
|
||||
|
||||
// starpostangle is to the first valid nextwaypoint for simplicity
|
||||
// if we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix
|
||||
// their map!
|
||||
for (i = 0U; i < bestwaypoint->numnextwaypoints; i++)
|
||||
{
|
||||
aimwaypoint = bestwaypoint->nextwaypoints[i];
|
||||
|
||||
if ((i == bestwaypoint->numnextwaypoints - 1U)
|
||||
|| ((K_GetWaypointIsEnabled(aimwaypoint) == true)
|
||||
&& (K_GetWaypointIsSpawnpoint(aimwaypoint) == true)))
|
||||
{
|
||||
player->starpostangle = R_PointToAngle2(
|
||||
bestwaypoint->mobj->x, bestwaypoint->mobj->y, aimwaypoint->mobj->x, aimwaypoint->mobj->y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
player->respawnvars.wp = bestwaypoint;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6281,7 +5898,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
|||
{
|
||||
if ((player != NULL) && (player->mo != NULL))
|
||||
{
|
||||
if (player->exiting)
|
||||
if (player->exiting || player->spectator)
|
||||
{
|
||||
player->nextwaypoint = K_GetFinishLineWaypoint();
|
||||
player->distancetofinish = 0U;
|
||||
|
|
@ -6896,7 +6513,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
player->pflags |= PF_ATTACKDOWN;
|
||||
|
||||
if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && leveltime > starttime
|
||||
&& player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && player->kartstuff[k_respawn] == 0)
|
||||
&& player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && (player->respawnvars.respawnstate == RESPAWNST_NONE))
|
||||
{
|
||||
// First, the really specific, finicky items that function without the item being directly in your item slot.
|
||||
// Karma item dropping
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid)
|
|||
void K_KartPainEnergyFling(player_t *player);
|
||||
void K_FlipFromObject(mobj_t *mo, mobj_t *master);
|
||||
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||
void K_DoIngameRespawn(player_t *player);
|
||||
void K_RespawnChecker(player_t *player);
|
||||
void K_SpawnDashDustRelease(player_t *player);
|
||||
void K_KartMoveAnimation(player_t *player);
|
||||
void K_KartPlayerHUDUpdate(player_t *player);
|
||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
||||
|
|
|
|||
735
src/k_respawn.c
Normal file
735
src/k_respawn.c
Normal file
|
|
@ -0,0 +1,735 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2020 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 k_respawn.c
|
||||
/// \brief Respawning logic
|
||||
|
||||
#include "k_respawn.h"
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
#include "k_kart.h"
|
||||
#include "k_battle.h"
|
||||
#include "g_game.h"
|
||||
#include "p_local.h"
|
||||
#include "p_tick.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "p_slopes.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_RespawnOffset(player_t *player, boolean flip)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
fixed_t K_RespawnOffset(player_t *player, boolean flip)
|
||||
{
|
||||
fixed_t z = 0;
|
||||
|
||||
if (flip == true)
|
||||
{
|
||||
player->mo->flags2 |= MF2_OBJECTFLIP;
|
||||
player->mo->eflags |= MFE_VERTICALFLIP;
|
||||
z -= (128 * mapobjectscale) - (player->mo->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->flags2 &= ~MF2_OBJECTFLIP;
|
||||
player->mo->eflags &= ~MFE_VERTICALFLIP;
|
||||
z += (128 * mapobjectscale);
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
|
||||
Updates a player's respawn variables to go to the provided waypoint.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
waypoint - Waypoint to respawn to.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
|
||||
{
|
||||
if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (waypoint == NULL || waypoint->mobj == NULL || P_MobjWasRemoved(waypoint->mobj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->respawnvars.pointx = waypoint->mobj->x;
|
||||
player->respawnvars.pointy = waypoint->mobj->y;
|
||||
player->respawnvars.pointz = waypoint->mobj->z;
|
||||
player->respawnvars.flip = (waypoint->mobj->flags2 & MF2_OBJECTFLIP);
|
||||
player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoIngameRespawn(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_DoIngameRespawn(player_t *player)
|
||||
{
|
||||
if (!player->mo || P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (leveltime <= starttime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->kartstuff[k_ringboost] = 0;
|
||||
player->kartstuff[k_driftboost] = 0;
|
||||
player->kartstuff[k_drift] = 0;
|
||||
player->kartstuff[k_driftcharge] = 0;
|
||||
player->kartstuff[k_pogospring] = 0;
|
||||
|
||||
// Set up respawn position if invalid
|
||||
if (player->respawnvars.wp != NULL)
|
||||
{
|
||||
K_RespawnAtWaypoint(player, player->respawnvars.wp);
|
||||
player->respawnvars.distanceleft = (RESPAWN_DIST * mapobjectscale) / FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 bestdist = UINT32_MAX;
|
||||
mapthing_t *beststart = NULL;
|
||||
UINT8 numstarts = 0;
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
numstarts = numcoopstarts;
|
||||
}
|
||||
else if (G_BattleGametype())
|
||||
{
|
||||
numstarts = numdmstarts;
|
||||
}
|
||||
|
||||
if (numstarts > 0)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
|
||||
for (i = 0; i < numstarts; i++)
|
||||
{
|
||||
UINT32 dist = UINT32_MAX;
|
||||
mapthing_t *checkstart = NULL;
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
checkstart = playerstarts[i];
|
||||
}
|
||||
else if (G_BattleGametype())
|
||||
{
|
||||
checkstart = deathmatchstarts[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
dist = (UINT32)P_AproxDistance((player->mo->x >> FRACBITS) - checkstart->x,
|
||||
(player->mo->y >> FRACBITS) - checkstart->y);
|
||||
|
||||
if (dist < bestdist)
|
||||
{
|
||||
beststart = checkstart;
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (beststart == NULL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "No respawn points!\n");
|
||||
player->respawnvars.pointx = 0;
|
||||
player->respawnvars.pointy = 0;
|
||||
player->respawnvars.pointz = 0;
|
||||
player->respawnvars.flip = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sector_t *s;
|
||||
fixed_t z = (beststart->options >> ZSHIFT) * FRACUNIT;
|
||||
|
||||
player->respawnvars.pointx = beststart->x << FRACBITS;
|
||||
player->respawnvars.pointy = beststart->y << FRACBITS;
|
||||
|
||||
s = R_PointInSubsector(beststart->x << FRACBITS, beststart->y << FRACBITS)->sector;
|
||||
|
||||
player->respawnvars.flip = (beststart->options & MTF_OBJECTFLIP);
|
||||
|
||||
if (player->respawnvars.flip == true)
|
||||
{
|
||||
player->respawnvars.pointz = (
|
||||
#ifdef ESLOPE
|
||||
s->c_slope ? P_GetZAt(s->c_slope, player->respawnvars.pointx, player->respawnvars.pointy) :
|
||||
#endif
|
||||
s->ceilingheight);
|
||||
|
||||
if (z != 0)
|
||||
{
|
||||
player->respawnvars.pointz -= z;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->respawnvars.pointz = (
|
||||
#ifdef ESLOPE
|
||||
s->f_slope ? P_GetZAt(s->f_slope, player->respawnvars.pointx, player->respawnvars.pointy) :
|
||||
#endif
|
||||
s->floorheight);
|
||||
|
||||
if (z)
|
||||
{
|
||||
player->respawnvars.pointz += z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
player->respawnvars.pointz += K_RespawnOffset(player, player->respawnvars.flip);
|
||||
player->respawnvars.distanceleft = 0;
|
||||
}
|
||||
|
||||
player->respawnvars.timer = RESPAWN_TIME;
|
||||
player->respawnvars.respawnstate = RESPAWNST_MOVE;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint)
|
||||
|
||||
Returns the index for the next respawn waypoint.
|
||||
|
||||
Input Arguments:-
|
||||
waypoint - Waypoint to look after.
|
||||
|
||||
Return:-
|
||||
An table index for waypoint_t -> nextwaypoints.
|
||||
--------------------------------------------------*/
|
||||
static size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint)
|
||||
{
|
||||
size_t i = 0U;
|
||||
size_t newwaypoint = SIZE_MAX;
|
||||
|
||||
// Set to the first valid nextwaypoint, for simplicity's sake.
|
||||
// If we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix their map!
|
||||
for (i = 0U; i < waypoint->numnextwaypoints; i++)
|
||||
{
|
||||
newwaypoint = i;
|
||||
|
||||
if ((i == waypoint->numnextwaypoints - 1U)
|
||||
|| ((K_GetWaypointIsEnabled(waypoint->nextwaypoints[newwaypoint]) == true)
|
||||
&& (K_GetWaypointIsSpawnpoint(waypoint->nextwaypoints[newwaypoint]) == true)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return newwaypoint;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_MovePlayerToRespawnPoint(player_t *player)
|
||||
|
||||
Handles the movement state of the respawn animation.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_MovePlayerToRespawnPoint(player_t *player)
|
||||
{
|
||||
const fixed_t realstepamt = (64 * mapobjectscale);
|
||||
fixed_t stepamt = realstepamt;
|
||||
|
||||
vertex_t dest, step, laser;
|
||||
angle_t stepha, stepva;
|
||||
fixed_t dist, fulldist;
|
||||
|
||||
UINT8 lasersteps = 4;
|
||||
UINT32 laserdist;
|
||||
waypoint_t *laserwp;
|
||||
boolean laserflip;
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
|
||||
player->powers[pw_flashing] = 2;
|
||||
player->powers[pw_nocontrol] = 2;
|
||||
|
||||
if (leveltime % 8 == 0 && !mapreset)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s3kcas);
|
||||
}
|
||||
|
||||
dest.x = player->respawnvars.pointx;
|
||||
dest.y = player->respawnvars.pointy;
|
||||
dest.z = player->respawnvars.pointz;
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(
|
||||
player->mo->x - dest.x,
|
||||
player->mo->y - dest.y),
|
||||
player->mo->z - dest.z
|
||||
);
|
||||
|
||||
if (dist <= stepamt)
|
||||
{
|
||||
// Reduce by the amount we needed to get to this waypoint
|
||||
stepamt -= dist;
|
||||
|
||||
// We've reached the destination point,
|
||||
P_UnsetThingPosition(player->mo);
|
||||
player->mo->x = dest.x;
|
||||
player->mo->y = dest.y;
|
||||
player->mo->z = dest.z;
|
||||
P_SetThingPosition(player->mo);
|
||||
|
||||
// Find the next waypoint to head towards
|
||||
if (player->respawnvars.wp != NULL)
|
||||
{
|
||||
size_t nwp = K_NextRespawnWaypointIndex(player->respawnvars.wp);
|
||||
|
||||
if (nwp == SIZE_MAX)
|
||||
{
|
||||
player->respawnvars.respawnstate = RESPAWNST_DROP;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set angle, regardless of if we're done or not
|
||||
player->frameangle = R_PointToAngle2(
|
||||
player->mo->x, player->mo->y,
|
||||
dest.x, dest.y
|
||||
);
|
||||
|
||||
if ((player->respawnvars.distanceleft == 0)
|
||||
&& (K_GetWaypointIsSpawnpoint(player->respawnvars.wp) == true))
|
||||
{
|
||||
// Alright buddy, that's the end of the ride.
|
||||
player->respawnvars.respawnstate = RESPAWNST_DROP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawnvars.distanceleft > player->respawnvars.wp->nextwaypointdistances[nwp])
|
||||
{
|
||||
player->respawnvars.distanceleft -= player->respawnvars.wp->nextwaypointdistances[nwp];
|
||||
}
|
||||
else
|
||||
{
|
||||
player->respawnvars.distanceleft = 0;
|
||||
}
|
||||
|
||||
player->respawnvars.wp = player->respawnvars.wp->nextwaypoints[nwp];
|
||||
K_RespawnAtWaypoint(player, player->respawnvars.wp);
|
||||
|
||||
dest.x = player->respawnvars.pointx;
|
||||
dest.y = player->respawnvars.pointy;
|
||||
dest.z = player->respawnvars.pointz;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We can now drop!
|
||||
player->respawnvars.respawnstate = RESPAWNST_DROP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
stepha = R_PointToAngle2(
|
||||
player->mo->x, player->mo->y,
|
||||
dest.x, dest.y
|
||||
);
|
||||
|
||||
stepva = R_PointToAngle2(
|
||||
0, player->mo->z,
|
||||
P_AproxDistance(player->mo->x - dest.x, player->mo->y - dest.y), dest.z
|
||||
);
|
||||
|
||||
// Move toward the respawn point
|
||||
player->frameangle = stepha;
|
||||
|
||||
step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt);
|
||||
|
||||
if (stepamt > 0)
|
||||
{
|
||||
player->mo->momx = step.x;
|
||||
player->mo->momy = step.y;
|
||||
player->mo->momz = step.z;
|
||||
}
|
||||
|
||||
// NOW THEN, time for loads of dumb duplication!
|
||||
// "Emulate" the rest of the path, that way we can spawn a particle a certain distance ahead of you.
|
||||
|
||||
if (stepamt != realstepamt)
|
||||
{
|
||||
// Reset back to default
|
||||
stepamt = realstepamt;
|
||||
|
||||
step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt);
|
||||
}
|
||||
|
||||
laserdist = player->respawnvars.distanceleft;
|
||||
laserwp = player->respawnvars.wp;
|
||||
laserflip = player->respawnvars.flip;
|
||||
|
||||
laser.x = player->mo->x + (step.x / 2);
|
||||
laser.y = player->mo->y + (step.y / 2);
|
||||
laser.z = player->mo->z + (step.z / 2);
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(
|
||||
laser.x - dest.x,
|
||||
laser.y - dest.y),
|
||||
laser.z - dest.z
|
||||
);
|
||||
fulldist = dist + (laserdist * FRACUNIT);
|
||||
|
||||
while (lasersteps > 0)
|
||||
{
|
||||
if (fulldist <= stepamt)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (dist <= stepamt)
|
||||
{
|
||||
size_t lnwp;
|
||||
|
||||
laser.x = dest.x;
|
||||
laser.y = dest.y;
|
||||
laser.z = dest.z;
|
||||
|
||||
if (laserdist <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lnwp = K_NextRespawnWaypointIndex(laserwp);
|
||||
if (lnwp == SIZE_MAX)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (laserdist > laserwp->nextwaypointdistances[lnwp])
|
||||
{
|
||||
laserdist -= laserwp->nextwaypointdistances[lnwp];
|
||||
}
|
||||
else
|
||||
{
|
||||
laserdist = 0;
|
||||
}
|
||||
|
||||
laserwp = laserwp->nextwaypoints[lnwp];
|
||||
|
||||
dest.x = laserwp->mobj->x;
|
||||
dest.y = laserwp->mobj->y;
|
||||
dest.z = laserwp->mobj->z;
|
||||
laserflip = (laserwp->mobj->flags2 & MF2_OBJECTFLIP);
|
||||
|
||||
if (laserflip == true)
|
||||
{
|
||||
dest.z -= (128 * mapobjectscale) - (player->mo->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.z += (128 * mapobjectscale);
|
||||
}
|
||||
|
||||
stepamt -= dist;
|
||||
|
||||
stepha = R_PointToAngle2(laser.x, laser.y, dest.x, dest.y);
|
||||
stepva = R_PointToAngle2(0, laser.z, P_AproxDistance(laser.x - dest.x, laser.y - dest.y), dest.z);
|
||||
|
||||
step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt);
|
||||
}
|
||||
else if (stepamt != realstepamt)
|
||||
{
|
||||
// Reset back to default
|
||||
stepamt = realstepamt;
|
||||
|
||||
step.x = FixedMul(FixedMul(FINECOSINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.y = FixedMul(FixedMul(FINESINE(stepha >> ANGLETOFINESHIFT), stepamt), FINECOSINE(stepva >> ANGLETOFINESHIFT));
|
||||
step.z = FixedMul(FINESINE(stepva >> ANGLETOFINESHIFT), 2*stepamt);
|
||||
}
|
||||
|
||||
if (stepamt > 0)
|
||||
{
|
||||
laser.x += step.x;
|
||||
laser.y += step.y;
|
||||
laser.z += step.z;
|
||||
}
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(
|
||||
laser.x - dest.x,
|
||||
laser.y - dest.y),
|
||||
laser.z - dest.z
|
||||
);
|
||||
fulldist = dist + (laserdist * FRACUNIT);
|
||||
|
||||
lasersteps--;
|
||||
}
|
||||
|
||||
if (lasersteps == 0) // Don't spawn them beyond the respawn point.
|
||||
{
|
||||
mobj_t *lasermo = P_SpawnMobj(laser.x, laser.y, laser.z + (player->mo->height / 2), MT_DEZLASER);
|
||||
|
||||
if (lasermo && !P_MobjWasRemoved(lasermo))
|
||||
{
|
||||
P_SetMobjState(lasermo, S_DEZLASER_TRAIL1);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
lasermo->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
P_SetTarget(&lasermo->target, player->mo);
|
||||
|
||||
lasermo->angle = stepha + ANGLE_90;
|
||||
P_SetScale(lasermo, (lasermo->destscale = player->mo->scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_HandleDropDash(player_t *player)
|
||||
|
||||
Handles the visuals for the waiting period,
|
||||
before you're allowed to Drop Dash.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_DropDashWait(player_t *player)
|
||||
{
|
||||
player->respawnvars.timer--;
|
||||
|
||||
if (leveltime % 8 == 0)
|
||||
{
|
||||
const UINT8 ns = 8;
|
||||
const angle_t sidediff = FixedAngle((360 / ns) * FRACUNIT);
|
||||
UINT8 i;
|
||||
|
||||
if (!mapreset)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s3kcas);
|
||||
}
|
||||
|
||||
for (i = 0; i < ns; i++)
|
||||
{
|
||||
const angle_t newangle = sidediff * i;
|
||||
vertex_t spawn;
|
||||
mobj_t *laser;
|
||||
|
||||
spawn.x = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
|
||||
spawn.y = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
spawn.z = player->mo->z + player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn.z = player->mo->z;
|
||||
}
|
||||
|
||||
laser = P_SpawnMobj(spawn.x, spawn.y, spawn.z, MT_DEZLASER);
|
||||
|
||||
if (laser && !P_MobjWasRemoved(laser))
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
laser->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
P_SetTarget(&laser->target, player->mo);
|
||||
|
||||
laser->angle = newangle + ANGLE_90;
|
||||
laser->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
|
||||
P_SetScale(laser, (laser->destscale = player->mo->scale));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_HandleDropDash(player_t *player)
|
||||
|
||||
Handles input for the Drop Dash maneuver.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
static void K_HandleDropDash(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
if (player->kartstuff[k_growshrinktimer] < 0)
|
||||
{
|
||||
player->mo->scalespeed = mapobjectscale/TICRATE;
|
||||
player->mo->destscale = (6*mapobjectscale)/8;
|
||||
|
||||
if (cv_kartdebugshrink.value && !modeattacking && !player->bot)
|
||||
{
|
||||
player->mo->destscale = (6*player->mo->destscale)/8;
|
||||
}
|
||||
}
|
||||
|
||||
if (!P_IsObjectOnGround(player->mo))
|
||||
{
|
||||
if (mapreset)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
||||
|
||||
// The old behavior was stupid and prone to accidental usage.
|
||||
// Let's rip off Mania instead, and turn this into a Drop Dash!
|
||||
|
||||
if ((cmd->buttons & BT_ACCELERATE) && !player->kartstuff[k_spinouttimer]) // Since we're letting players spin out on respawn, don't let them charge a dropdash in this state. (It wouldn't work anyway)
|
||||
{
|
||||
player->respawnvars.dropdash++;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->respawnvars.dropdash = 0;
|
||||
}
|
||||
|
||||
if (player->respawnvars.dropdash == TICRATE/4)
|
||||
{
|
||||
S_StartSound(player->mo, sfx_ddash);
|
||||
}
|
||||
|
||||
if ((player->respawnvars.dropdash >= TICRATE/4) && (player->respawnvars.dropdash & 1))
|
||||
{
|
||||
player->mo->colorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->colorized = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((cmd->buttons & BT_ACCELERATE) && (player->respawnvars.dropdash >= TICRATE/4))
|
||||
{
|
||||
S_StartSound(player->mo, sfx_s23c);
|
||||
player->kartstuff[k_startboost] = 50;
|
||||
K_SpawnDashDustRelease(player);
|
||||
}
|
||||
|
||||
player->mo->colorized = false;
|
||||
player->respawnvars.dropdash = 0;
|
||||
|
||||
//P_PlayRinglossSound(player->mo);
|
||||
P_PlayerRingBurst(player, 3);
|
||||
|
||||
if (G_BattleGametype())
|
||||
{
|
||||
if (player->kartstuff[k_bumper] > 0)
|
||||
{
|
||||
if (player->kartstuff[k_bumper] == 1)
|
||||
{
|
||||
mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!!
|
||||
P_SetTarget(&karmahitbox->target, player->mo);
|
||||
karmahitbox->destscale = player->mo->scale;
|
||||
P_SetScale(karmahitbox, player->mo->scale);
|
||||
CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]);
|
||||
}
|
||||
player->kartstuff[k_bumper]--;
|
||||
if (K_IsPlayerWanted(player))
|
||||
K_CalculateBattleWanted();
|
||||
}
|
||||
|
||||
if (!player->kartstuff[k_bumper])
|
||||
{
|
||||
player->kartstuff[k_comebacktimer] = comebacktime;
|
||||
if (player->kartstuff[k_comebackmode] == 2)
|
||||
{
|
||||
mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE);
|
||||
S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound);
|
||||
player->kartstuff[k_comebackmode] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
K_CheckBumpers();
|
||||
}
|
||||
|
||||
player->respawnvars.respawnstate = RESPAWNST_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_RespawnChecker(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_RespawnChecker(player_t *player)
|
||||
{
|
||||
if (player->respawnvars.respawnstate == RESPAWNST_NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->spectator)
|
||||
{
|
||||
player->respawnvars.respawnstate = RESPAWNST_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (player->respawnvars.respawnstate)
|
||||
{
|
||||
case RESPAWNST_MOVE:
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
K_MovePlayerToRespawnPoint(player);
|
||||
return;
|
||||
case RESPAWNST_DROP:
|
||||
player->mo->momx = player->mo->momy = 0;
|
||||
if (player->respawnvars.timer > 0)
|
||||
{
|
||||
player->mo->momz = 0;
|
||||
K_DropDashWait(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_HandleDropDash(player);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
player->respawnvars.respawnstate = RESPAWNST_NONE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
72
src/k_respawn.h
Normal file
72
src/k_respawn.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2018-2020 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 k_respawn.h
|
||||
/// \brief Respawning logic
|
||||
|
||||
#ifndef __K_RESPAWN__
|
||||
#define __K_RESPAWN__
|
||||
|
||||
#include "k_waypoint.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#define RESPAWN_DIST 1024
|
||||
#define RESPAWN_TIME 48
|
||||
#define RESPAWNST_NONE 0
|
||||
#define RESPAWNST_MOVE 1
|
||||
#define RESPAWNST_DROP 2
|
||||
|
||||
/*--------------------------------------------------
|
||||
fixed_t K_RespawnOffset(player_t *player, boolean flip);
|
||||
|
||||
Updates the player's flip flags, and returns a
|
||||
Z offset for respawning.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform this for.
|
||||
flip - false for normal, true for gravity flip.
|
||||
|
||||
Return:-
|
||||
Z position offset.
|
||||
--------------------------------------------------*/
|
||||
|
||||
fixed_t K_RespawnOffset(player_t *player, boolean flip);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_DoIngameRespawn(player_t *player);
|
||||
|
||||
Starts the respawning animation for the specified player,
|
||||
updating their respawn variables in preparation.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform this for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_DoIngameRespawn(player_t *player);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_RespawnChecker(player_t *player);
|
||||
|
||||
Thinker for the respawning animation.
|
||||
|
||||
Input Arguments:-
|
||||
player - Player to preform this for.
|
||||
|
||||
Return:-
|
||||
true if the player is not supposed to collide with geometry,
|
||||
otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_RespawnChecker(player_t *player);
|
||||
|
||||
#endif
|
||||
|
|
@ -294,18 +294,8 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->weapondelay);
|
||||
else if (fastcmp(field,"tossdelay"))
|
||||
lua_pushinteger(L, plr->tossdelay);
|
||||
else if (fastcmp(field,"starpostx"))
|
||||
lua_pushinteger(L, plr->starpostx);
|
||||
else if (fastcmp(field,"starposty"))
|
||||
lua_pushinteger(L, plr->starposty);
|
||||
else if (fastcmp(field,"starpostz"))
|
||||
lua_pushinteger(L, plr->starpostz);
|
||||
else if (fastcmp(field,"starpostnum"))
|
||||
lua_pushinteger(L, plr->starpostnum);
|
||||
else if (fastcmp(field,"starposttime"))
|
||||
lua_pushinteger(L, plr->starposttime);
|
||||
else if (fastcmp(field,"starpostangle"))
|
||||
lua_pushangle(L, plr->starpostangle);
|
||||
else if (fastcmp(field,"angle_pos"))
|
||||
lua_pushangle(L, plr->angle_pos);
|
||||
else if (fastcmp(field,"old_angle_pos"))
|
||||
|
|
@ -544,18 +534,8 @@ static int player_set(lua_State *L)
|
|||
plr->weapondelay = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"tossdelay"))
|
||||
plr->tossdelay = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starpostx"))
|
||||
plr->starpostx = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starposty"))
|
||||
plr->starposty = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starpostz"))
|
||||
plr->starpostz = (INT16)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starpostnum"))
|
||||
plr->starpostnum = (INT32)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starposttime"))
|
||||
plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"starpostangle"))
|
||||
plr->starpostangle = luaL_checkangle(L, 3);
|
||||
else if (fastcmp(field,"angle_pos"))
|
||||
plr->angle_pos = luaL_checkangle(L, 3);
|
||||
else if (fastcmp(field,"old_angle_pos"))
|
||||
|
|
|
|||
|
|
@ -682,13 +682,11 @@ void Command_Savecheckpoint_f(void)
|
|||
REQUIRE_INLEVEL;
|
||||
REQUIRE_SINGLEPLAYER;
|
||||
|
||||
players[consoleplayer].starposttime = players[consoleplayer].realtime;
|
||||
players[consoleplayer].starpostx = players[consoleplayer].mo->x>>FRACBITS;
|
||||
players[consoleplayer].starposty = players[consoleplayer].mo->y>>FRACBITS;
|
||||
players[consoleplayer].starpostz = players[consoleplayer].mo->floorz>>FRACBITS;
|
||||
players[consoleplayer].starpostangle = players[consoleplayer].mo->angle;
|
||||
players[consoleplayer].respawnvars.pointx = players[consoleplayer].mo->x;
|
||||
players[consoleplayer].respawnvars.pointy = players[consoleplayer].mo->y;
|
||||
players[consoleplayer].respawnvars.pointz = players[consoleplayer].mo->floorz;
|
||||
|
||||
CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].starpostx, players[consoleplayer].starposty, players[consoleplayer].starpostz);
|
||||
CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].respawnvars.pointx, players[consoleplayer].respawnvars.pointy, players[consoleplayer].respawnvars.pointz);
|
||||
}
|
||||
|
||||
// Like M_GetAllEmeralds() but for console devmode junkies.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_waypoint.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
@ -5638,10 +5639,8 @@ void A_MixUp(mobj_t *actor)
|
|||
INT32 transspeed; //player speed
|
||||
|
||||
// Starpost stuff
|
||||
INT16 starpostx, starposty, starpostz;
|
||||
fixed_t starpostx, starposty, starpostz;
|
||||
INT32 starpostnum;
|
||||
tic_t starposttime;
|
||||
angle_t starpostangle;
|
||||
|
||||
INT32 mflags2;
|
||||
|
||||
|
|
@ -5680,22 +5679,20 @@ void A_MixUp(mobj_t *actor)
|
|||
z = players[one].mo->z;
|
||||
angle = players[one].mo->angle;
|
||||
|
||||
starpostx = players[one].starpostx;
|
||||
starposty = players[one].starposty;
|
||||
starpostz = players[one].starpostz;
|
||||
starpostangle = players[one].starpostangle;
|
||||
starpostx = players[one].respawnvars.pointx;
|
||||
starposty = players[one].respawnvars.pointy;
|
||||
starpostz = players[one].respawnvars.pointz;
|
||||
starpostnum = players[one].starpostnum;
|
||||
starposttime = players[one].starposttime;
|
||||
|
||||
mflags2 = players[one].mo->flags2;
|
||||
|
||||
P_MixUp(players[one].mo, players[two].mo->x, players[two].mo->y, players[two].mo->z, players[two].mo->angle,
|
||||
players[two].starpostx, players[two].starposty, players[two].starpostz,
|
||||
players[two].starpostnum, players[two].starposttime, players[two].starpostangle,
|
||||
players[two].respawnvars.pointx, players[two].respawnvars.pointy, players[two].respawnvars.pointz,
|
||||
players[two].starpostnum, 0, 0,
|
||||
players[two].mo->flags2);
|
||||
|
||||
P_MixUp(players[two].mo, x, y, z, angle, starpostx, starposty, starpostz,
|
||||
starpostnum, starposttime, starpostangle,
|
||||
starpostnum, 0, 0,
|
||||
mflags2);
|
||||
|
||||
//flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for...
|
||||
|
|
@ -5720,10 +5717,8 @@ void A_MixUp(mobj_t *actor)
|
|||
INT32 transspeed[MAXPLAYERS]; //player speed
|
||||
|
||||
// Star post stuff
|
||||
INT16 spposition[MAXPLAYERS][3];
|
||||
fixed_t spposition[MAXPLAYERS][3];
|
||||
INT32 starpostnum[MAXPLAYERS];
|
||||
tic_t starposttime[MAXPLAYERS];
|
||||
angle_t starpostangle[MAXPLAYERS];
|
||||
|
||||
INT32 flags2[MAXPLAYERS];
|
||||
|
||||
|
|
@ -5754,12 +5749,10 @@ void A_MixUp(mobj_t *actor)
|
|||
transspeed[counter] = players[i].speed;
|
||||
transtracer[counter] = players[i].mo->tracer;
|
||||
|
||||
spposition[counter][0] = players[i].starpostx;
|
||||
spposition[counter][1] = players[i].starposty;
|
||||
spposition[counter][2] = players[i].starpostz;
|
||||
spposition[counter][0] = players[i].respawnvars.pointx;
|
||||
spposition[counter][1] = players[i].respawnvars.pointy;
|
||||
spposition[counter][2] = players[i].respawnvars.pointz;
|
||||
starpostnum[counter] = players[i].starpostnum;
|
||||
starposttime[counter] = players[i].starposttime;
|
||||
starpostangle[counter] = players[i].starpostangle;
|
||||
|
||||
flags2[counter] = players[i].mo->flags2;
|
||||
|
||||
|
|
@ -5799,7 +5792,7 @@ void A_MixUp(mobj_t *actor)
|
|||
|
||||
P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom],
|
||||
spposition[teleportfrom][0], spposition[teleportfrom][1], spposition[teleportfrom][2],
|
||||
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
|
||||
starpostnum[teleportfrom], 0, 0,
|
||||
flags2[teleportfrom]);
|
||||
|
||||
//...flags after. same reasoning.
|
||||
|
|
@ -8612,7 +8605,7 @@ void A_SPBChase(mobj_t *actor)
|
|||
if (players[i].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (players[i].kartstuff[k_respawn])
|
||||
if (players[i].respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
continue;*/ // respawning
|
||||
|
||||
if (players[i].kartstuff[k_position] < bestrank)
|
||||
|
|
@ -8789,7 +8782,7 @@ void A_SPBChase(mobj_t *actor)
|
|||
|
||||
actor->lastlook = -1; // Just make sure this is reset
|
||||
|
||||
if (!player || !player->mo || player->mo->health <= 0 || player->kartstuff[k_respawn])
|
||||
if (!player || !player->mo || player->mo->health <= 0 || (player->respawnvars.respawnstate != RESPAWNST_NONE))
|
||||
{
|
||||
// No one there? Completely STOP.
|
||||
actor->momx = actor->momy = actor->momz = 0;
|
||||
|
|
|
|||
|
|
@ -1428,8 +1428,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
case MT_STARPOST:
|
||||
if (player->bot)
|
||||
return;
|
||||
//
|
||||
// SRB2kart: make sure the player will have enough checkpoints to touch
|
||||
|
||||
if (circuitmap && special->health - player->starpostnum > 1)
|
||||
{
|
||||
// blatant reuse of a variable that's normally unused in circuit
|
||||
|
|
@ -1449,11 +1448,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
if (player->starpostnum >= special->health)
|
||||
return; // Already hit this post
|
||||
|
||||
// Save the player's time and position.
|
||||
player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x
|
||||
player->starpostnum = special->health;
|
||||
|
||||
//S_StartSound(toucher, special->info->painsound);
|
||||
return;
|
||||
|
||||
case MT_FAKEMOBILE:
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "k_kart.h" // SRB2kart 011617
|
||||
#include "k_collide.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
#include "hu_stuff.h" // SRB2kart
|
||||
#include "i_system.h" // SRB2kart
|
||||
|
|
|
|||
30
src/p_mobj.c
30
src/p_mobj.c
|
|
@ -38,6 +38,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "k_battle.h"
|
||||
#include "k_color.h"
|
||||
#include "k_respawn.h"
|
||||
|
||||
// protos.
|
||||
//static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}};
|
||||
|
|
@ -11877,7 +11878,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
// Spawn with a pity shield if necessary.
|
||||
//P_DoPityCheck(p);
|
||||
|
||||
if (p->kartstuff[k_respawn] != 0)
|
||||
if (p->respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
p->mo->flags |= MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY;
|
||||
|
||||
if (G_BattleGametype()) // SRB2kart
|
||||
|
|
@ -12025,16 +12026,12 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
z = ceiling - mobjinfo[MT_PLAYER].height;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z -= ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
if (p->kartstuff[k_respawn])
|
||||
z -= 128*mapobjectscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
z = floor;
|
||||
if (mthing->options >> ZSHIFT)
|
||||
z += ((mthing->options >> ZSHIFT) << FRACBITS);
|
||||
if (p->kartstuff[k_respawn])
|
||||
z += 128*mapobjectscale;
|
||||
}
|
||||
|
||||
if (mthing->options & MTF_OBJECTFLIP) // flip the player!
|
||||
|
|
@ -12046,6 +12043,11 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing)
|
|||
else
|
||||
z = floor;
|
||||
|
||||
if (p->respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
{
|
||||
z += K_RespawnOffset(p, (mthing->options & MTF_OBJECTFLIP));
|
||||
}
|
||||
|
||||
if (z < floor)
|
||||
z = floor;
|
||||
else if (z > ceiling - mobjinfo[MT_PLAYER].height)
|
||||
|
|
@ -12078,9 +12080,11 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
mobj_t *mobj = p->mo;
|
||||
I_Assert(mobj != NULL);
|
||||
|
||||
K_DoIngameRespawn(p);
|
||||
|
||||
P_UnsetThingPosition(mobj);
|
||||
mobj->x = p->starpostx << FRACBITS;
|
||||
mobj->y = p->starposty << FRACBITS;
|
||||
mobj->x = p->respawnvars.pointx;
|
||||
mobj->y = p->respawnvars.pointy;
|
||||
P_SetThingPosition(mobj);
|
||||
sector = R_PointInSubsector(mobj->x, mobj->y)->sector;
|
||||
|
||||
|
|
@ -12095,12 +12099,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
#endif
|
||||
sector->ceilingheight;
|
||||
|
||||
if (mobj->player->kartstuff[k_starpostflip])
|
||||
z = (p->starpostz<<FRACBITS) - (128 * mapobjectscale) - mobj->height;
|
||||
else
|
||||
z = (p->starpostz<<FRACBITS) + (128 * mapobjectscale);
|
||||
|
||||
mobj->player->kartstuff[k_starpostflip] = 0;
|
||||
z = p->respawnvars.pointz;
|
||||
|
||||
if (z < floor)
|
||||
z = floor;
|
||||
|
|
@ -12114,12 +12113,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
|
|||
if (mobj->z == mobj->floorz)
|
||||
mobj->eflags |= MFE_ONGROUND;
|
||||
|
||||
mobj->angle = p->starpostangle;
|
||||
|
||||
P_AfterPlayerSpawn(playernum);
|
||||
|
||||
//if (!(netgame || multiplayer))
|
||||
// leveltime = p->starposttime;
|
||||
}
|
||||
|
||||
#define MAXHUNTEMERALDS 64
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT16(save_p, players[i].totalring);
|
||||
WRITEUINT32(save_p, players[i].realtime);
|
||||
WRITEUINT8(save_p, players[i].laps);
|
||||
WRITEINT32(save_p, players[i].starpostnum);
|
||||
|
||||
////////////////////
|
||||
// CTF Mode Stuff //
|
||||
|
|
@ -198,13 +199,6 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT32(save_p, players[i].weapondelay);
|
||||
WRITEINT32(save_p, players[i].tossdelay);
|
||||
|
||||
WRITEUINT32(save_p, players[i].starposttime);
|
||||
WRITEINT16(save_p, players[i].starpostx);
|
||||
WRITEINT16(save_p, players[i].starposty);
|
||||
WRITEINT16(save_p, players[i].starpostz);
|
||||
WRITEINT32(save_p, players[i].starpostnum);
|
||||
WRITEANGLE(save_p, players[i].starpostangle);
|
||||
|
||||
WRITEANGLE(save_p, players[i].angle_pos);
|
||||
WRITEANGLE(save_p, players[i].old_angle_pos);
|
||||
|
||||
|
|
@ -368,6 +362,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].totalring = READINT16(save_p); // Total number of rings obtained for Race Mode
|
||||
players[i].realtime = READUINT32(save_p); // integer replacement for leveltime
|
||||
players[i].laps = READUINT8(save_p); // Number of laps (optional)
|
||||
players[i].starpostnum = READINT32(save_p);
|
||||
|
||||
////////////////////
|
||||
// CTF Mode Stuff //
|
||||
|
|
@ -378,13 +373,6 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].weapondelay = READINT32(save_p);
|
||||
players[i].tossdelay = READINT32(save_p);
|
||||
|
||||
players[i].starposttime = READUINT32(save_p);
|
||||
players[i].starpostx = READINT16(save_p);
|
||||
players[i].starposty = READINT16(save_p);
|
||||
players[i].starpostz = READINT16(save_p);
|
||||
players[i].starpostnum = READINT32(save_p);
|
||||
players[i].starpostangle = READANGLE(save_p);
|
||||
|
||||
players[i].angle_pos = READANGLE(save_p);
|
||||
players[i].old_angle_pos = READANGLE(save_p);
|
||||
|
||||
|
|
|
|||
|
|
@ -3250,13 +3250,7 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
else // gametype is GT_COOP or GT_RACE
|
||||
{
|
||||
players[i].mo = NULL;
|
||||
|
||||
if (players[i].starposttime)
|
||||
{
|
||||
G_SpawnPlayer(i, true);
|
||||
}
|
||||
else
|
||||
G_SpawnPlayer(i, false);
|
||||
G_SpawnPlayer(i, (players[i].starpostnum != 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "console.h" // CON_LogMessage
|
||||
#include "k_respawn.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
@ -2111,7 +2112,6 @@ static void K_HandleLapIncrement(player_t *player)
|
|||
curlap = 0;
|
||||
}
|
||||
|
||||
player->starposttime = player->realtime;
|
||||
player->starpostnum = 0;
|
||||
|
||||
if (P_IsDisplayPlayer(player))
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP;
|
||||
UINT8 i;
|
||||
|
||||
(void)starposttime;
|
||||
(void)starpostangle;
|
||||
|
||||
// the move is ok,
|
||||
// so link the thing into its new position
|
||||
P_UnsetThingPosition(thing);
|
||||
|
|
@ -92,11 +95,9 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
|
|||
thing->player->speed = 0;
|
||||
|
||||
// Starpost information
|
||||
thing->player->starpostx = starpostx;
|
||||
thing->player->starposty = starposty;
|
||||
thing->player->starpostz = starpostz;
|
||||
thing->player->starposttime = starposttime;
|
||||
thing->player->starpostangle = starpostangle;
|
||||
thing->player->respawnvars.pointx = starpostx;
|
||||
thing->player->respawnvars.pointy = starposty;
|
||||
thing->player->respawnvars.pointz = starpostz;
|
||||
thing->player->starpostnum = starpostnum;
|
||||
|
||||
P_ResetPlayer(thing->player);
|
||||
|
|
|
|||
30
src/p_user.c
30
src/p_user.c
|
|
@ -47,6 +47,7 @@
|
|||
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
|
||||
#include "k_kart.h"
|
||||
#include "console.h" // CON_LogMessage
|
||||
#include "k_respawn.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
@ -5772,7 +5773,7 @@ static void P_MovePlayer(player_t *player)
|
|||
// Kart: store the current turn range for later use
|
||||
if ((player->mo && player->speed > 0) // Moving
|
||||
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|
||||
|| (player->kartstuff[k_respawn]) // Respawning
|
||||
|| (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawning
|
||||
|| (player->spectator || objectplacing)) // Not a physical player
|
||||
{
|
||||
player->lturn_max[leveltime%MAXPREDICTTICS] = K_GetKartTurnValue(player, KART_FULLTURN)+1;
|
||||
|
|
@ -8607,19 +8608,34 @@ void P_PlayerThink(player_t *player)
|
|||
player->linkcount = 0;
|
||||
}
|
||||
|
||||
// Move around.
|
||||
// Reactiontime is used to prevent movement
|
||||
// for a bit after a teleport.
|
||||
if (player->mo->reactiontime)
|
||||
if (player->respawnvars.respawnstate != RESPAWNST_NONE)
|
||||
{
|
||||
K_RespawnChecker(player);
|
||||
player->rmomx = player->rmomy = 0;
|
||||
|
||||
if (player->respawnvars.respawnstate == RESPAWNST_DROP)
|
||||
{
|
||||
// Allows some turning
|
||||
P_MovePlayer(player);
|
||||
}
|
||||
}
|
||||
else if (player->mo->reactiontime)
|
||||
{
|
||||
// Reactiontime is used to prevent movement
|
||||
// for a bit after a teleport.
|
||||
player->mo->reactiontime--;
|
||||
}
|
||||
else if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT)
|
||||
{
|
||||
P_DoZoomTube(player);
|
||||
player->rmomx = player->rmomy = 0; // no actual momentum from your controls
|
||||
player->rmomx = player->rmomy = 0;
|
||||
P_ResetScore(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move around.
|
||||
P_MovePlayer(player);
|
||||
}
|
||||
|
||||
if (!player->mo)
|
||||
return; // P_MovePlayer removed player->mo.
|
||||
|
|
@ -8796,7 +8812,7 @@ void P_PlayerThink(player_t *player)
|
|||
if (!(//player->pflags & PF_NIGHTSMODE ||
|
||||
player->kartstuff[k_hyudorotimer] // SRB2kart - fixes Hyudoro not flashing when it should.
|
||||
|| player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either.
|
||||
|| player->kartstuff[k_respawn] // Respawn timer (for drop dash effect)
|
||||
|| (player->respawnvars.respawnstate != RESPAWNST_NONE) // Respawn timer (for drop dash effect)
|
||||
|| (player->pflags & PF_TIMEOVER) // NO CONTEST explosion
|
||||
|| (G_BattleGametype() && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])
|
||||
|| leveltime < starttime)) // Level intro
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue