From 90ca38acb066883bce043d7824e12ee4ca376824 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 5 Feb 2021 01:24:23 -0500 Subject: [PATCH] Store where the finish line beam should be displayed Instead of figuring out where it should be every tick while it's visible, store where it'll be at the start of the map. Also moved finish line beam into a new file, k_race.c/h, for any Race-specific code. A few unused variables for sprint map support later too --- src/CMakeLists.txt | 2 + src/Makefile | 1 + src/k_kart.c | 244 ---------------------------- src/k_race.c | 387 +++++++++++++++++++++++++++++++++++++++++++++ src/k_race.h | 70 ++++++++ src/p_setup.c | 13 ++ src/p_tick.c | 1 + 7 files changed, 474 insertions(+), 244 deletions(-) create mode 100644 src/k_race.c create mode 100644 src/k_race.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d461a820..42006e423 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -170,6 +170,7 @@ set(SRB2_CORE_GAME_SOURCES p_telept.c p_tick.c p_user.c + k_race.c k_battle.c k_bheap.c k_collide.c @@ -195,6 +196,7 @@ set(SRB2_CORE_GAME_SOURCES p_slopes.h p_spec.h p_tick.h + k_race.h k_battle.h k_bheap.h k_collide.h diff --git a/src/Makefile b/src/Makefile index de857fd1d..3499dd24a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -558,6 +558,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/k_respawn.o\ $(OBJDIR)/k_collide.o\ $(OBJDIR)/k_color.o \ + $(OBJDIR)/k_race.o \ $(OBJDIR)/k_battle.o \ $(OBJDIR)/k_pwrlv.o \ $(OBJDIR)/k_waypoint.o\ diff --git a/src/k_kart.c b/src/k_kart.c index 5b259a050..fd485a5cf 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3106,250 +3106,6 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I return NULL; } -// Spawns the finish line fault-indicator effect -#define FINISHLINEBEAM_SPACING (48*mapobjectscale) -static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *line, boolean reverse) -{ - const fixed_t linelength = P_AproxDistance(line->dx, line->dy); - const fixed_t xstep = FixedDiv(line->dx, linelength); - const fixed_t ystep = FixedDiv(line->dy, linelength); - - fixed_t linex = line->v1->x; - fixed_t liney = line->v1->y; - angle_t lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) + ANGLE_90; - - UINT8 i; - - if (line->flags & ML_NOCLIMB) - { - // Line is flipped - lineangle += ANGLE_180; - } - - linex += FixedMul(offset, xstep); - liney += FixedMul(offset, ystep); - - while (offset < linelength) - { -#define COLORCYCLELEN 10 - const UINT8 colorcycle[COLORCYCLELEN] = { - SKINCOLOR_PERIWINKLE, - SKINCOLOR_SLATE, - SKINCOLOR_BLOSSOM, - SKINCOLOR_RASPBERRY, - SKINCOLOR_ORANGE, - SKINCOLOR_YELLOW, - SKINCOLOR_LIME, - SKINCOLOR_TURTLE, - SKINCOLOR_ROBIN, - SKINCOLOR_JAWZ - }; - - const UINT8 numframes = 5; - const angle_t framethreshold = ANGLE_180 / (numframes-1); - const angle_t frameaim = aiming + (framethreshold / 2); - - fixed_t x, y, z; - UINT8 spriteframe = 0; - - x = linex + FixedMul(FixedMul(FINISHLINEBEAM_SPACING, FINECOSINE(lineangle >> ANGLETOFINESHIFT)), FINECOSINE(aiming >> ANGLETOFINESHIFT)); - y = liney + FixedMul(FixedMul(FINISHLINEBEAM_SPACING, FINESINE(lineangle >> ANGLETOFINESHIFT)), FINECOSINE(aiming >> ANGLETOFINESHIFT)); - z = FINISHLINEBEAM_SPACING + FixedMul(FINISHLINEBEAM_SPACING, FINESINE(aiming >> ANGLETOFINESHIFT)); - - if (leveltime >= starttime) - { - spriteframe = 4; // Weakest sprite when passable - } - else if (frameaim > ANGLE_180) - { - spriteframe = (ANGLE_MAX - frameaim) / framethreshold; - } - else - { - spriteframe = frameaim / framethreshold; - } - - for (i = 0; i <= r_splitscreen; i++) - { - if (playeringame[displayplayers[i]] && players[displayplayers[i]].mo && !P_MobjWasRemoved(players[displayplayers[i]].mo)) - { - mobj_t *beam; - - beam = P_SpawnMobj(x, y, players[displayplayers[i]].mo->z + z, MT_THOK); - P_SetMobjState(beam, S_FINISHBEAM1 + spriteframe); - - beam->colorized = true; - beam->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - - if (reverse) - { - beam->color = colorcycle[((leveltime / 4) + (COLORCYCLELEN/2)) % COLORCYCLELEN]; - } - else - { - beam->color = colorcycle[(leveltime / 4) % COLORCYCLELEN]; - } - } - } - - offset += FINISHLINEBEAM_SPACING; - linex += FixedMul(FINISHLINEBEAM_SPACING, xstep); - liney += FixedMul(FINISHLINEBEAM_SPACING, ystep); - - if (reverse) - { - aiming -= ANGLE_45; - } - else - { - aiming += ANGLE_45; - } - } - - for (i = 0; i <= r_splitscreen; i++) - { - if (playeringame[displayplayers[i]] && players[displayplayers[i]].mo && !P_MobjWasRemoved(players[displayplayers[i]].mo)) - { - UINT8 j; - for (j = 0; j < 2; j++) - { - vertex_t *v = line->v1; - mobj_t *end1, *end2; - angle_t a = R_PointToAngle2(0, 0, line->dx, line->dy); - fixed_t sx; - fixed_t sy; - - //if (line->flags & ML_NOCLIMB) - //{ - //a += ANGLE_180; - //} - - sx = FixedMul(3*mapobjectscale, FINECOSINE(a >> ANGLETOFINESHIFT)); - sy = FixedMul(3*mapobjectscale, FINESINE(a >> ANGLETOFINESHIFT)); - - if (j == 1) - { - v = line->v2; - sx = -sx; - sy = -sy; - } - - end1 = P_SpawnMobj( - v->x + sx, - v->y + sy, - players[displayplayers[i]].mo->z + FINISHLINEBEAM_SPACING, - MT_THOK - ); - - P_SetMobjState(end1, S_FINISHBEAMEND1); - end1->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - end1->angle = lineangle; - - end2 = P_SpawnMobj( - v->x + (8*sx), - v->y + (8*sy), - players[displayplayers[i]].mo->z + FINISHLINEBEAM_SPACING, - MT_THOK - ); - - P_SetMobjState(end2, S_FINISHBEAMEND2); - end2->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); - end2->angle = lineangle; - - P_SetTarget(&end2->tracer, end1); - end2->flags2 |= MF2_LINKDRAW; - } - } - } -} - -void K_RunFinishLineBeam(void) -{ - INT64 bounds[4]; - angle_t angle = 0; - UINT32 flags = 0; - boolean valid = false; - UINT32 i; - - if (!(leveltime < starttime || rainbowstartavailable == true)) - { - return; - } - - // this does NOT support finish lines that curve. - // I wanted to! But I have a headache from trying to code it for like, 3 hours! - // so I'm not! - - bounds[0] = INT64_MAX; // min x - bounds[1] = INT64_MIN; // max x - bounds[2] = INT64_MAX; // min y - bounds[3] = INT64_MIN; // max y - - for (i = 0; i < numlines; i++) - { - if (lines[i].special == 2001) - { - angle_t thisAngle = R_PointToAngle2(0, 0, lines[i].dx, lines[i].dy); - - bounds[0] = min(bounds[0], min(lines[i].v1->x, lines[i].v2->x)); // min x - bounds[1] = max(bounds[1], max(lines[i].v1->x, lines[i].v2->x)); // max x - bounds[2] = min(bounds[2], min(lines[i].v1->y, lines[i].v2->y)); // min y - bounds[3] = max(bounds[3], max(lines[i].v1->y, lines[i].v2->y)); // max y - - if (valid == false) - { - angle = thisAngle; - flags = lines[i].flags; - } - else if (angle != thisAngle) - { - valid = false; - break; - } - - valid = true; - } - } - - if (valid == true) - { - fixed_t span = P_AproxDistance(bounds[1] - bounds[0], bounds[3] - bounds[2]) / 2; - - fixed_t cx = (bounds[0] + bounds[1]) / 2; - fixed_t cy = (bounds[2] + bounds[3]) / 2; - - vertex_t v1, v2; // fake vertexes - line_t junk; // fake linedef - - const angle_t angoffset = ANGLE_45; - const angle_t angadd = ANGLE_11hh; - const fixed_t speed = 6 * mapobjectscale; - - fixed_t offseta = (leveltime * speed) % FINISHLINEBEAM_SPACING; - angle_t aiminga = (angoffset * -((leveltime * speed) / FINISHLINEBEAM_SPACING)) + (angadd * leveltime); - - fixed_t offsetb = FINISHLINEBEAM_SPACING - offseta; - angle_t aimingb = (angoffset * -((leveltime * speed) / FINISHLINEBEAM_SPACING)) - (angadd * leveltime); - - v1.x = cx - FixedMul(span, FINECOSINE(angle >> ANGLETOFINESHIFT)); - v1.y = cy - FixedMul(span, FINESINE(angle >> ANGLETOFINESHIFT)); - - v2.x = cx + FixedMul(span, FINECOSINE(angle >> ANGLETOFINESHIFT)); - v2.y = cy + FixedMul(span, FINESINE(angle >> ANGLETOFINESHIFT)); - - junk.v1 = &v1; - junk.v2 = &v2; - junk.dx = v2.x - v1.x; - junk.dy = v2.y - v1.y; - junk.flags = flags; - - K_DrawFinishLineBeamForLine(offseta, aiminga, &junk, false); - K_DrawFinishLineBeamForLine(offsetb, aimingb, &junk, true); - } -} - -#undef FINISHLINEBEAM_SPACING - UINT16 K_DriftSparkColor(player_t *player, INT32 charge) { INT32 ds = K_GetKartDriftSparkValue(player); diff --git a/src/k_race.c b/src/k_race.c new file mode 100644 index 000000000..2e74fa65c --- /dev/null +++ b/src/k_race.c @@ -0,0 +1,387 @@ +// 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_race.c +/// \brief Race Mode specific code. + +#include "k_race.h" + +#include "k_kart.h" +#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" +#include "m_random.h" +#include "p_local.h" +#include "p_slopes.h" +#include "p_setup.h" +#include "r_draw.h" +#include "r_local.h" +#include "s_sound.h" +#include "st_stuff.h" +#include "v_video.h" +#include "z_zone.h" +#include "m_misc.h" +#include "m_cond.h" +#include "f_finale.h" +#include "lua_hud.h" // For Lua hud checks +#include "lua_hook.h" // For MobjDamage and ShouldDamage +#include "m_cheat.h" // objectplacing +#include "p_spec.h" + +#include "k_waypoint.h" +#include "k_bot.h" +#include "k_hud.h" + +static line_t *finishBeamLine = NULL; + +mobj_t *beamPoints[2]; +UINT8 numBeamPoints = 0; + +/*-------------------------------------------------- + void K_ClearFinishBeamLine(void) + + See header file for description. +--------------------------------------------------*/ +void K_ClearFinishBeamLine(void) +{ + finishBeamLine = NULL; +} + +/*-------------------------------------------------- + static void K_FreeFinishBeamLine(void) + + See header file for description. +--------------------------------------------------*/ +static void K_FreeFinishBeamLine(void) +{ + if (finishBeamLine != NULL) + { + if (finishBeamLine->v1 != NULL) + { + Z_Free(finishBeamLine->v1); + } + + if (finishBeamLine->v2 != NULL) + { + Z_Free(finishBeamLine->v2); + } + + Z_Free(finishBeamLine); + } + + K_ClearFinishBeamLine(); +} + +/*-------------------------------------------------- + static void K_CreateFinishLineFromPoints(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) + + See header file for description. +--------------------------------------------------*/ +static void K_CreateFinishLineFromPoints(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) +{ + I_Assert(finishBeamLine == NULL); // Needs to be NULL + + finishBeamLine = Z_Calloc(sizeof (*finishBeamLine), PU_LEVEL, NULL); + + finishBeamLine->v1 = Z_Calloc(sizeof (*finishBeamLine->v1), PU_LEVEL, NULL); + finishBeamLine->v1->x = x1; + finishBeamLine->v1->y = y1; + + finishBeamLine->v2 = Z_Calloc(sizeof (*finishBeamLine->v2), PU_LEVEL, NULL); + finishBeamLine->v2->x = x2; + finishBeamLine->v2->y = y2; + + finishBeamLine->dx = x2 - x1; + finishBeamLine->dy = y2 - y1; + + finishBeamLine->flags = 0; +} + +/*-------------------------------------------------- + boolean K_GenerateFinishBeamLine(void) + + See header file for description. +--------------------------------------------------*/ +boolean K_GenerateFinishBeamLine(void) +{ + INT64 bounds[4]; + angle_t angle; + + boolean valid = false; + size_t i; + + // Ensure everything's freed by this time. + K_FreeFinishBeamLine(); + + // + // TODO: create from beam point objs before resorting to auto generate + // + + bounds[0] = INT64_MAX; // min x + bounds[1] = INT64_MIN; // max x + bounds[2] = INT64_MAX; // min y + bounds[3] = INT64_MIN; // max y + + for (i = 0; i < numlines; i++) + { + angle_t thisAngle; + + if (lines[i].special != 2001) + { + continue; + } + + thisAngle = R_PointToAngle2(0, 0, lines[i].dx, lines[i].dy); + + bounds[0] = min(bounds[0], min(lines[i].v1->x, lines[i].v2->x)); // min x + bounds[1] = max(bounds[1], max(lines[i].v1->x, lines[i].v2->x)); // max x + bounds[2] = min(bounds[2], min(lines[i].v1->y, lines[i].v2->y)); // min y + bounds[3] = max(bounds[3], max(lines[i].v1->y, lines[i].v2->y)); // max y + + if (valid == false) + { + angle = thisAngle; + valid = true; + } + else if (angle != thisAngle) + { + // Do not even attempt to bother with curved finish lines. + // Will likely just crash. + valid = false; + + break; + } + } + + if (valid == true) + { + fixed_t span = P_AproxDistance(bounds[1] - bounds[0], bounds[3] - bounds[2]) / 2; + + fixed_t cx = (bounds[0] + bounds[1]) / 2; + fixed_t cy = (bounds[2] + bounds[3]) / 2; + + fixed_t spanC = FixedMul(span, FINECOSINE(angle >> ANGLETOFINESHIFT)); + fixed_t spanS = FixedMul(span, FINESINE(angle >> ANGLETOFINESHIFT)); + + K_CreateFinishLineFromPoints( + cx - spanC, cy - spanS, + cx + spanC, cy + spanS + ); + + return true; + } + + return false; +} + +/*-------------------------------------------------- + static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *line, boolean reverse) + + Draws a helix out of rainbow colored orbs along a line, unique for each display player. + Called twice for the finish line beam effect. + + Input Arguments:- + offset - Offset value for positioning. Changed every tick to make it animate. + aiming - Starting vertical angle value. Changed every tick to make it animate. + line - Linedef to draw along. + reverse - Draw in reverse. Call twice with this toggled to make a double helix. + + Return:- + None +--------------------------------------------------*/ + +static void K_DrawFinishLineBeamForLine(fixed_t offset, angle_t aiming, line_t *line, boolean reverse) +{ + const fixed_t linelength = P_AproxDistance(line->dx, line->dy); + const fixed_t xstep = FixedDiv(line->dx, linelength); + const fixed_t ystep = FixedDiv(line->dy, linelength); + + fixed_t linex = line->v1->x; + fixed_t liney = line->v1->y; + angle_t lineangle = R_PointToAngle2(0, 0, line->dx, line->dy) + ANGLE_90; + + UINT8 i; + + if (line->flags & ML_NOCLIMB) + { + // Line is flipped + lineangle += ANGLE_180; + } + + linex += FixedMul(offset, xstep); + liney += FixedMul(offset, ystep); + + while (offset < linelength) + { +#define COLORCYCLELEN 10 + const UINT8 colorcycle[COLORCYCLELEN] = { + SKINCOLOR_PERIWINKLE, + SKINCOLOR_SLATE, + SKINCOLOR_BLOSSOM, + SKINCOLOR_RASPBERRY, + SKINCOLOR_ORANGE, + SKINCOLOR_YELLOW, + SKINCOLOR_LIME, + SKINCOLOR_TURTLE, + SKINCOLOR_ROBIN, + SKINCOLOR_JAWZ + }; + + const UINT8 numframes = 5; + const angle_t framethreshold = ANGLE_180 / (numframes-1); + const angle_t frameaim = aiming + (framethreshold / 2); + + fixed_t x, y, z; + UINT8 spriteframe = 0; + + x = linex + FixedMul(FixedMul(FINISHLINEBEAM_SPACING, FINECOSINE(lineangle >> ANGLETOFINESHIFT)), FINECOSINE(aiming >> ANGLETOFINESHIFT)); + y = liney + FixedMul(FixedMul(FINISHLINEBEAM_SPACING, FINESINE(lineangle >> ANGLETOFINESHIFT)), FINECOSINE(aiming >> ANGLETOFINESHIFT)); + z = FINISHLINEBEAM_SPACING + FixedMul(FINISHLINEBEAM_SPACING, FINESINE(aiming >> ANGLETOFINESHIFT)); + + if (leveltime >= starttime) + { + spriteframe = 4; // Weakest sprite when passable + } + else if (frameaim > ANGLE_180) + { + spriteframe = (ANGLE_MAX - frameaim) / framethreshold; + } + else + { + spriteframe = frameaim / framethreshold; + } + + for (i = 0; i <= r_splitscreen; i++) + { + if (playeringame[displayplayers[i]] && players[displayplayers[i]].mo && !P_MobjWasRemoved(players[displayplayers[i]].mo)) + { + mobj_t *beam; + + beam = P_SpawnMobj(x, y, players[displayplayers[i]].mo->z + z, MT_THOK); + P_SetMobjState(beam, S_FINISHBEAM1 + spriteframe); + + beam->colorized = true; + beam->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); + + if (reverse) + { + beam->color = colorcycle[((leveltime / 4) + (COLORCYCLELEN/2)) % COLORCYCLELEN]; + } + else + { + beam->color = colorcycle[(leveltime / 4) % COLORCYCLELEN]; + } + } + } + + offset += FINISHLINEBEAM_SPACING; + linex += FixedMul(FINISHLINEBEAM_SPACING, xstep); + liney += FixedMul(FINISHLINEBEAM_SPACING, ystep); + + if (reverse) + { + aiming -= ANGLE_45; + } + else + { + aiming += ANGLE_45; + } + } + + for (i = 0; i <= r_splitscreen; i++) + { + if (playeringame[displayplayers[i]] && players[displayplayers[i]].mo && !P_MobjWasRemoved(players[displayplayers[i]].mo)) + { + UINT8 j; + for (j = 0; j < 2; j++) + { + vertex_t *v = line->v1; + mobj_t *end1, *end2; + angle_t a = R_PointToAngle2(0, 0, line->dx, line->dy); + fixed_t sx; + fixed_t sy; + + /* + if (line->flags & ML_NOCLIMB) + { + a += ANGLE_180; + } + */ + + sx = FixedMul(3*mapobjectscale, FINECOSINE(a >> ANGLETOFINESHIFT)); + sy = FixedMul(3*mapobjectscale, FINESINE(a >> ANGLETOFINESHIFT)); + + if (j == 1) + { + v = line->v2; + sx = -sx; + sy = -sy; + } + + end1 = P_SpawnMobj( + v->x + sx, + v->y + sy, + players[displayplayers[i]].mo->z + FINISHLINEBEAM_SPACING, + MT_THOK + ); + + P_SetMobjState(end1, S_FINISHBEAMEND1); + end1->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); + end1->angle = lineangle; + + end2 = P_SpawnMobj( + v->x + (8*sx), + v->y + (8*sy), + players[displayplayers[i]].mo->z + FINISHLINEBEAM_SPACING, + MT_THOK + ); + + P_SetMobjState(end2, S_FINISHBEAMEND2); + end2->drawflags = MFD_DONTDRAW & ~K_GetPlayerDontDrawFlag(&players[displayplayers[i]]); + end2->angle = lineangle; + + P_SetTarget(&end2->tracer, end1); + end2->flags2 |= MF2_LINKDRAW; + } + } + } +} + +/*-------------------------------------------------- + void K_RunFinishLineBeam(void) + + See header file for description. +--------------------------------------------------*/ + +void K_RunFinishLineBeam(void) +{ + if (!(leveltime < starttime || rainbowstartavailable == true)) + { + return; + } + + if (finishBeamLine != NULL) + { + const angle_t angoffset = ANGLE_45; + const angle_t angadd = ANGLE_11hh; + const fixed_t speed = 6 * mapobjectscale; + + fixed_t offseta = (leveltime * speed) % FINISHLINEBEAM_SPACING; + angle_t aiminga = (angoffset * -((leveltime * speed) / FINISHLINEBEAM_SPACING)) + (angadd * leveltime); + + fixed_t offsetb = FINISHLINEBEAM_SPACING - offseta; + angle_t aimingb = (angoffset * -((leveltime * speed) / FINISHLINEBEAM_SPACING)) - (angadd * leveltime); + + K_DrawFinishLineBeamForLine(offseta, aiminga, finishBeamLine, false); + K_DrawFinishLineBeamForLine(offsetb, aimingb, finishBeamLine, true); + } +} diff --git a/src/k_race.h b/src/k_race.h new file mode 100644 index 000000000..e25944422 --- /dev/null +++ b/src/k_race.h @@ -0,0 +1,70 @@ +// 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_race.h +/// \brief Race Mode specific code. + +#ifndef __K_RACE__ +#define __K_RACE__ + +#include "r_defs.h" + +extern mobj_t *beamPoints[2]; +extern UINT8 numBeamPoints; + +#define FINISHLINEBEAM_SPACING (48*mapobjectscale) + +/*-------------------------------------------------- + void K_ClearFinishBeamLine(void); + + Clears variables for finishBeamLine. + Separate from K_FreeFinishBeamLine since this + needs called when PU_LEVEL is freed. + + Input Arguments:- + None + + Return:- + None +--------------------------------------------------*/ + +void K_ClearFinishBeamLine(void); + + +/*-------------------------------------------------- + boolean K_GenerateFinishBeamLine(void); + + Finds pre-placed "beam points" to create a finish line out of, + or tries to automatically create it from a finish linedef in the map. + The result is stored in the "finishBeamLine" variable. + + Input Arguments:- + None + + Return:- + True if successful, otherwise false. +--------------------------------------------------*/ + +boolean K_GenerateFinishBeamLine(void); + + +/*-------------------------------------------------- + void K_RunFinishLineBeam(void); + + Updates the finish line beam effect. + + Input Arguments:- + None + + Return:- + None +--------------------------------------------------*/ + +void K_RunFinishLineBeam(void); + +#endif diff --git a/src/p_setup.c b/src/p_setup.c index 13c0170a8..8baaf581d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -83,6 +83,7 @@ // SRB2Kart #include "k_kart.h" +#include "k_race.h" #include "k_battle.h" // K_SpawnBattleCapsules #include "k_pwrlv.h" #include "k_waypoint.h" @@ -3609,6 +3610,11 @@ static void P_ResetSpawnpoints(void) for (i = 0; i < 16; i++) skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + + // SRB2Kart + numBeamPoints = 0; + for (i = 0; i < 2; i++) + beamPoints[i] = NULL; } static void P_LoadRecordGhosts(void) @@ -4059,6 +4065,8 @@ boolean P_LoadLevel(boolean fromnetsave) // The waypoint data that's in PU_LEVEL needs to be reset back to 0/NULL now since PU_LEVEL was cleared K_ClearWaypoints(); + K_ClearFinishBeamLine(); + // Load the waypoints please! if (gametyperules & GTR_CIRCUIT) { @@ -4066,6 +4074,11 @@ boolean P_LoadLevel(boolean fromnetsave) { CONS_Alert(CONS_ERROR, "Waypoints were not able to be setup! Player positions will not work correctly.\n"); } + + if (K_GenerateFinishBeamLine() == false) + { + CONS_Alert(CONS_ERROR, "No valid finish line beam setup could be found.\n"); + } } #ifdef HWRENDER // not win32 only 19990829 by Kin diff --git a/src/p_tick.c b/src/p_tick.c index 4d4ba4b26..71ded772c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -30,6 +30,7 @@ // SRB2Kart #include "k_kart.h" +#include "k_race.h" #include "k_battle.h" #include "k_waypoint.h"