mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-25 20:01:04 +00:00
Huge restructuring & more fine-tuned speed, following, & turn behavior
This commit is contained in:
parent
8d6e203bd2
commit
7556cca505
6 changed files with 141 additions and 50 deletions
Binary file not shown.
|
@ -1932,8 +1932,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju
|
|||
if (player->health <= 0)
|
||||
return;
|
||||
|
||||
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0
|
||||
|| player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0
|
||||
if (/*player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 0 // Explosions should combo, because of SPB and Eggman
|
||||
||*/player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0
|
||||
|| (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)))
|
||||
{
|
||||
K_DoInstashield(player);
|
||||
|
@ -3949,7 +3949,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (player->kartstuff[k_eggmanexplode] <= 0)
|
||||
{
|
||||
mobj_t *eggsexplode;
|
||||
player->powers[pw_flashing] = 0;
|
||||
//player->powers[pw_flashing] = 0;
|
||||
eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SPBEXPLOSION);
|
||||
if (player->kartstuff[k_eggmanblame] >= 0
|
||||
&& player->kartstuff[k_eggmanblame] < MAXPLAYERS
|
||||
|
@ -4878,7 +4878,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
|||
if (player->kartstuff[k_itemtype] == KITEM_SPB
|
||||
|| player->kartstuff[k_itemtype] == KITEM_SHRINK
|
||||
|| player->kartstuff[k_growshrinktimer] < 0)
|
||||
indirectitemcooldown = 30*TICRATE;
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
|
||||
if (player->kartstuff[k_hyudorotimer] > 0)
|
||||
{
|
||||
|
|
172
src/p_enemy.c
172
src/p_enemy.c
|
@ -8327,87 +8327,171 @@ void A_SPBChase(mobj_t *actor)
|
|||
UINT8 bestrank = UINT8_MAX;
|
||||
fixed_t dist;
|
||||
angle_t hang, vang;
|
||||
fixed_t wspeed, xyspeed, zspeed;
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_SPBChase", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (actor->threshold)
|
||||
// Default speed
|
||||
wspeed = FixedMul(actor->info->speed, mapheaderinfo[gamemap-1]->mobj_scale);
|
||||
if (gamespeed == 0)
|
||||
wspeed = FixedMul(wspeed, FRACUNIT-FRACUNIT/4);
|
||||
else if (gamespeed == 2)
|
||||
wspeed = FixedMul(wspeed, FRACUNIT+FRACUNIT/4);
|
||||
|
||||
if (actor->threshold) // Just fired, go straight.
|
||||
{
|
||||
P_InstaThrust(actor, actor->angle, actor->info->speed);
|
||||
P_InstaThrust(actor, actor->angle, wspeed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor->extravalue1)
|
||||
if (actor->extravalue1) // MODE: TARGETING
|
||||
{
|
||||
if (actor->tracer && actor->tracer->health && actor->tracer->player)
|
||||
if (actor->tracer && actor->tracer->health)
|
||||
{
|
||||
fixed_t maxspeed = K_GetKartSpeed(actor->tracer->player, false) - (actor->tracer->scale);
|
||||
fixed_t defspeed = wspeed;
|
||||
fixed_t range = (160*actor->tracer->scale);
|
||||
|
||||
// Maybe we want SPB to target an object later? IDK lol
|
||||
if (actor->tracer->player) // 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel
|
||||
defspeed = ((33 - actor->tracer->player->kartspeed) * K_GetKartSpeed(actor->tracer->player, false)) / 32;
|
||||
|
||||
// Play the intimidating gurgle
|
||||
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||
S_StartSound(actor, actor->info->activesound);
|
||||
|
||||
dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z);
|
||||
|
||||
wspeed = FixedMul(defspeed, FRACUNIT + FixedDiv(dist-range, range));
|
||||
if (wspeed < defspeed)
|
||||
wspeed = defspeed;
|
||||
if (wspeed > defspeed*2)
|
||||
wspeed = defspeed*2;
|
||||
|
||||
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
|
||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
||||
|
||||
actor->momx = FixedMul(FixedMul(maxspeed, FINECOSINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT));
|
||||
actor->momy = FixedMul(FixedMul(maxspeed, FINESINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT));
|
||||
actor->momz = FixedMul(maxspeed, FINESINE(vang>>ANGLETOFINESHIFT));
|
||||
{
|
||||
// Smoothly rotate horz angle
|
||||
angle_t input = hang - actor->angle;
|
||||
boolean invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
|
||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->angle += input;
|
||||
|
||||
// Smoothly rotate vert angle
|
||||
input = vang - actor->movedir;
|
||||
invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->movedir += input;
|
||||
}
|
||||
|
||||
actor->momx = FixedMul(FixedMul(xyspeed, FINECOSINE(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));
|
||||
return;
|
||||
}
|
||||
else
|
||||
else // Target's gone, return to SEEKING
|
||||
{
|
||||
P_SetTarget(&actor->tracer, NULL);
|
||||
actor->extravalue1 = 0;
|
||||
actor->extravalue1 = 0; // Find someone new next tic
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
else // MODE: SEEKING
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
|
||||
if (players[i].exiting)
|
||||
continue; // exiting
|
||||
|
||||
if (!players[i].mo)
|
||||
continue; // no mobj
|
||||
|
||||
if (players[i].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (players[i].kartstuff[k_position] < bestrank)
|
||||
// Find the player with the best rank
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
bestrank = players[i].kartstuff[k_position];
|
||||
player = &players[i];
|
||||
}
|
||||
}
|
||||
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||
continue; // not in-game
|
||||
|
||||
if (player != NULL && player->mo)
|
||||
{
|
||||
if (!players[i].mo)
|
||||
continue; // no mobj
|
||||
|
||||
if (players[i].mo->health <= 0)
|
||||
continue; // dead
|
||||
|
||||
if (players[i].kartstuff[k_respawn])
|
||||
continue; // respawning
|
||||
|
||||
if (players[i].kartstuff[k_position] < bestrank)
|
||||
{
|
||||
bestrank = players[i].kartstuff[k_position];
|
||||
player = &players[i];
|
||||
}
|
||||
}
|
||||
|
||||
// No one there?
|
||||
if (player == NULL || !player->mo)
|
||||
return;
|
||||
|
||||
// Found someone, now get close enough to initiate the slaughter...
|
||||
P_SetTarget(&actor->tracer, player->mo);
|
||||
|
||||
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);
|
||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
||||
|
||||
actor->momx = FixedMul(FixedMul(actor->info->speed, FINECOSINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT));
|
||||
actor->momy = FixedMul(FixedMul(actor->info->speed, FINESINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT));
|
||||
actor->momz = FixedMul(actor->info->speed, FINESINE(vang>>ANGLETOFINESHIFT));
|
||||
|
||||
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
|
||||
|
||||
if (dist <= RING_DIST && (actor->z > actor->floorz && actor->z+actor->height < actor->ceilingz))
|
||||
{
|
||||
S_StartSound(actor, actor->info->attacksound);
|
||||
actor->extravalue1 = 1;
|
||||
// Smoothly rotate horz angle
|
||||
angle_t input = hang - actor->angle;
|
||||
boolean invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; it looks better and makes U-turns not unfair
|
||||
xyspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->angle += input;
|
||||
|
||||
// Smoothly rotate vert angle
|
||||
input = vang - actor->movedir;
|
||||
invert = (input > ANGLE_180);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
// Slow down when turning; might as well do it for momz, since we do it above too
|
||||
zspeed = FixedMul(wspeed, max(0, (((180<<FRACBITS) - AngleFixed(input)) / 90) - FRACUNIT));
|
||||
|
||||
input = FixedAngle(AngleFixed(input)/4);
|
||||
if (invert)
|
||||
input = InvAngle(input);
|
||||
|
||||
actor->movedir += input;
|
||||
}
|
||||
|
||||
actor->momx = FixedMul(FixedMul(xyspeed, FINECOSINE(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));
|
||||
|
||||
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.
|
||||
actor->extravalue1 = 1; // TARGET ACQUIRED
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -597,11 +597,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
|||
{
|
||||
mobj_t *spbexplode;
|
||||
|
||||
S_StopSound(special); // Don't continue playing the gurgle or the siren
|
||||
|
||||
if (!player->kartstuff[k_invincibilitytimer] && !player->kartstuff[k_growshrinktimer])
|
||||
{
|
||||
K_DropHnextList(player);
|
||||
K_StripItems(player);
|
||||
player->powers[pw_flashing] = 0;
|
||||
//player->powers[pw_flashing] = 0;
|
||||
}
|
||||
|
||||
spbexplode = P_SpawnMobj(toucher->x, toucher->y, toucher->z, MT_SPBEXPLOSION);
|
||||
|
|
|
@ -8168,8 +8168,10 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
break;
|
||||
case MT_BALLHOG:
|
||||
case MT_SPB:
|
||||
indirectitemcooldown = 20*TICRATE;
|
||||
/* FALLTHRU */
|
||||
case MT_BALLHOG:
|
||||
P_SpawnGhostMobj(mobj)->fuse = 3;
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
|
|
@ -7685,6 +7685,9 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
|
|||
P_InstaThrust(mo, R_PointToAngle2(inflictor->x, inflictor->y, mo->x, mo->y)+ANGLE_90, 16*FRACUNIT);
|
||||
}
|
||||
|
||||
if (mo->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown.
|
||||
indirectitemcooldown = 0;
|
||||
|
||||
if (mo == inflictor) // Don't nuke yourself, dummy!
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue