SPB Now follows the track.

You better watch out, You better watch out, You better watch out!
This commit is contained in:
Sryder 2019-06-28 22:43:34 +01:00
parent 10adecb4a6
commit 6eca35aae1
5 changed files with 106 additions and 56 deletions

View file

@ -15870,7 +15870,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_SPB_DEAD, // deathstate S_SPB_DEAD, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_s3k5d, // deathsound sfx_s3k5d, // deathsound
64*FRACUNIT, // speed 96*FRACUNIT, // speed
24*FRACUNIT, // radius 24*FRACUNIT, // radius
48*FRACUNIT, // height 48*FRACUNIT, // height
0, // display offset 0, // display offset

View file

@ -5672,48 +5672,6 @@ static void K_KartDrift(player_t *player, boolean onground)
player->kartstuff[k_brakedrift] = 0; player->kartstuff[k_brakedrift] = 0;
} }
/*--------------------------------------------------
static waypoint_t *K_GetPlayerClosestWaypoint(player_t *player)
Gets the closest waypoint of a player.
Input Arguments:-
player - The player the closest waypoint is being found for
Return:-
The waypoint that is the player's closest waypoint
--------------------------------------------------*/
static waypoint_t *K_GetPlayerClosestWaypoint(player_t *player)
{
waypoint_t *closestwaypoint = NULL;
if ((player != NULL) && (player->mo != NULL))
{
mobj_t *wpmobj;
mobj_t *closestwpmobj = NULL;
fixed_t wpdist = INT32_MAX;
fixed_t closestdist = INT32_MAX;
waypoint_t *waypoint = NULL;
// Find the closest waypoint mobj to the player
for (wpmobj = waypointcap; wpmobj; wpmobj = wpmobj->tracer)
{
wpdist = P_AproxDistance(wpmobj->x - player->mo->x, wpmobj->y - player->mo->y);
wpdist = P_AproxDistance(wpdist, wpmobj->z - player->mo->z);
if (wpdist < closestdist)
{
closestdist = wpdist;
closestwpmobj = wpmobj;
}
}
waypoint = K_SearchWaypointGraphForMobj(closestwpmobj);
closestwaypoint = waypoint;
}
return closestwaypoint;
}
/*-------------------------------------------------- /*--------------------------------------------------
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
@ -5729,11 +5687,11 @@ static waypoint_t *K_GetPlayerClosestWaypoint(player_t *player)
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player) static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{ {
waypoint_t *bestwaypoint = NULL; waypoint_t *bestwaypoint = NULL;
if ((player != NULL) && (player->mo != NULL)) if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false))
{ {
waypoint_t *waypoint = NULL; waypoint_t *waypoint = NULL;
waypoint = K_GetPlayerClosestWaypoint(player); waypoint = K_GetClosestWaypointToMobj(player->mo);
bestwaypoint = waypoint; bestwaypoint = waypoint;
// check the waypoint's location in relation to the player // check the waypoint's location in relation to the player

View file

@ -173,6 +173,43 @@ UINT32 K_GetCircuitLength(void)
return circuitlength; return circuitlength;
} }
/*--------------------------------------------------
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
See header file for description.
--------------------------------------------------*/
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
{
waypoint_t *closestwaypoint = NULL;
if ((mobj == NULL) || P_MobjWasRemoved(mobj))
{
CONS_Debug(DBG_GAMELOGIC, "NULL mobj in K_GetClosestWaypointToMobj.\n");
}
else
{
size_t i = 0U;
waypoint_t *checkwaypoint = NULL;
fixed_t closestdist = INT32_MAX;
fixed_t checkdist = INT32_MAX;
for (i = 0; i < numwaypoints; i++)
{
checkwaypoint = &waypointheap[i];
checkdist = P_AproxDistance(mobj->x - checkwaypoint->mobj->x, mobj->y - checkwaypoint->mobj->y);
checkdist = P_AproxDistance(checkdist, mobj->z - checkwaypoint->mobj->z);
if (checkdist < closestdist)
{
closestwaypoint = checkwaypoint;
closestdist = checkdist;
}
}
}
return closestwaypoint;
}
/*-------------------------------------------------- /*--------------------------------------------------
size_t K_GetWaypointHeapIndex(waypoint_t *waypoint) size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)

View file

@ -122,6 +122,20 @@ INT32 K_GetWaypointID(waypoint_t *waypoint);
UINT32 K_GetCircuitLength(void); UINT32 K_GetCircuitLength(void);
/*--------------------------------------------------
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj)
Returns the closest waypoint to an mobj
Input Arguments:-
mobj - mobj to get the closest waypoint of.
Return:-
The closest waypoint to the mobj
--------------------------------------------------*/
waypoint_t *K_GetClosestWaypointToMobj(mobj_t *const mobj);
/*-------------------------------------------------- /*--------------------------------------------------
boolean K_PathfindToWaypoint( boolean K_PathfindToWaypoint(
waypoint_t *const sourcewaypoint, waypoint_t *const sourcewaypoint,

View file

@ -24,6 +24,7 @@
#include "i_video.h" #include "i_video.h"
#include "lua_hook.h" #include "lua_hook.h"
#include "k_kart.h" // SRB2kart #include "k_kart.h" // SRB2kart
#include "k_waypoint.h"
#ifdef HW3SOUND #ifdef HW3SOUND
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
@ -8387,6 +8388,20 @@ void A_JawzExplode(mobj_t *actor)
return; return;
} }
static void SpawnSPBTrailRings(mobj_t *actor)
{
if (actor != NULL)
{
if (leveltime % 6 == 0)
{
mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momx,
actor->z - actor->momz + (24*mapobjectscale), MT_RING);
ring->threshold = 10;
ring->fuse = 120*TICRATE;
}
}
}
void A_SPBChase(mobj_t *actor) void A_SPBChase(mobj_t *actor)
{ {
player_t *player = NULL; player_t *player = NULL;
@ -8543,13 +8558,7 @@ void A_SPBChase(mobj_t *actor)
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT)); actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
// Spawn a trail of rings behind the SPB! // Spawn a trail of rings behind the SPB!
if (leveltime % 6 == 0) SpawnSPBTrailRings(actor);
{
mobj_t *ring = P_SpawnMobj(actor->x - actor->momx, actor->y - actor->momx,
actor->z - actor->momz + (24*mapobjectscale), MT_RING);
ring->threshold = 10;
ring->fuse = 120*TICRATE;
}
// Red speed lines for when it's gaining on its target. A tell for when you're starting to lose too much speed! // Red speed lines for when it's gaining on its target. A tell for when you're starting to lose too much speed!
if (R_PointToDist2(0, 0, actor->momx, actor->momy) > (actor->tracer->player ? (16*actor->tracer->player->speed)/15 if (R_PointToDist2(0, 0, actor->momx, actor->momy) > (actor->tracer->player ? (16*actor->tracer->player->speed)/15
@ -8610,6 +8619,8 @@ void A_SPBChase(mobj_t *actor)
} }
else // MODE: SEEKING else // MODE: SEEKING
{ {
waypoint_t *closestwaypoint = NULL;
waypoint_t *nextwaypoint = NULL;
actor->lastlook = -1; // Just make sure this is reset 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->kartstuff[k_respawn])
@ -8623,16 +8634,43 @@ void A_SPBChase(mobj_t *actor)
// Found someone, now get close enough to initiate the slaughter... // Found someone, now get close enough to initiate the slaughter...
// don't hurt players that have nothing to do with this: // Seeking SPB can now hurt people
actor->flags |= MF_NOCLIPTHING; actor->flags &= ~MF_NOCLIPTHING;
P_SetTarget(&actor->tracer, player->mo); P_SetTarget(&actor->tracer, player->mo);
spbplace = bestrank; spbplace = bestrank;
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z); dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); closestwaypoint = K_GetClosestWaypointToMobj(actor);
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z); if (closestwaypoint != NULL)
{
const boolean huntbackwards = false;
boolean useshortcuts = false;
// If the player is on a shortcut, use shortcuts. No escape.
if (K_GetWaypointIsShortcut(player->nextwaypoint))
{
useshortcuts = true;
}
nextwaypoint = K_GetNextWaypointToDestination(
closestwaypoint, player->nextwaypoint, useshortcuts, huntbackwards);
}
if (nextwaypoint != NULL)
{
const fixed_t xywaypointdist = P_AproxDistance(
actor->x - nextwaypoint->mobj->x, actor->y - nextwaypoint->mobj->y);
hang = R_PointToAngle2(actor->x, actor->y, nextwaypoint->mobj->x, nextwaypoint->mobj->y);
vang = R_PointToAngle2(0, actor->z, xywaypointdist, nextwaypoint->mobj->z);
}
else
{
// continue straight ahead... Shouldn't happen.
hang = actor->angle;
vang = 0U;
}
{ {
// Smoothly rotate horz angle // Smoothly rotate horz angle
@ -8670,6 +8708,9 @@ void A_SPBChase(mobj_t *actor)
actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT)); actor->momy = FixedMul(FixedMul(xyspeed, FINESINE(actor->angle>>ANGLETOFINESHIFT)), FINECOSINE(actor->movedir>>ANGLETOFINESHIFT));
actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT)); actor->momz = FixedMul(zspeed, FINESINE(actor->movedir>>ANGLETOFINESHIFT));
// Spawn a trail of rings behind the SPB!
SpawnSPBTrailRings(actor);
if (dist <= (3072*actor->tracer->scale)) // Close enough to target? if (dist <= (3072*actor->tracer->scale)) // Close enough to target?
{ {
S_StartSound(actor, actor->info->attacksound); // Siren sound; might not need this anymore, but I'm keeping it for now just for debugging. S_StartSound(actor, actor->info->attacksound); // Siren sound; might not need this anymore, but I'm keeping it for now just for debugging.