mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +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)
|
if (player->health <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_spinouttimer] > 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
|
||*/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)))
|
|| (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1)))
|
||||||
{
|
{
|
||||||
K_DoInstashield(player);
|
K_DoInstashield(player);
|
||||||
|
@ -3949,7 +3949,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
if (player->kartstuff[k_eggmanexplode] <= 0)
|
if (player->kartstuff[k_eggmanexplode] <= 0)
|
||||||
{
|
{
|
||||||
mobj_t *eggsexplode;
|
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);
|
eggsexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_SPBEXPLOSION);
|
||||||
if (player->kartstuff[k_eggmanblame] >= 0
|
if (player->kartstuff[k_eggmanblame] >= 0
|
||||||
&& player->kartstuff[k_eggmanblame] < MAXPLAYERS
|
&& player->kartstuff[k_eggmanblame] < MAXPLAYERS
|
||||||
|
@ -4878,7 +4878,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
if (player->kartstuff[k_itemtype] == KITEM_SPB
|
if (player->kartstuff[k_itemtype] == KITEM_SPB
|
||||||
|| player->kartstuff[k_itemtype] == KITEM_SHRINK
|
|| player->kartstuff[k_itemtype] == KITEM_SHRINK
|
||||||
|| player->kartstuff[k_growshrinktimer] < 0)
|
|| player->kartstuff[k_growshrinktimer] < 0)
|
||||||
indirectitemcooldown = 30*TICRATE;
|
indirectitemcooldown = 20*TICRATE;
|
||||||
|
|
||||||
if (player->kartstuff[k_hyudorotimer] > 0)
|
if (player->kartstuff[k_hyudorotimer] > 0)
|
||||||
{
|
{
|
||||||
|
|
146
src/p_enemy.c
146
src/p_enemy.c
|
@ -8327,55 +8327,102 @@ void A_SPBChase(mobj_t *actor)
|
||||||
UINT8 bestrank = UINT8_MAX;
|
UINT8 bestrank = UINT8_MAX;
|
||||||
fixed_t dist;
|
fixed_t dist;
|
||||||
angle_t hang, vang;
|
angle_t hang, vang;
|
||||||
|
fixed_t wspeed, xyspeed, zspeed;
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_SPBChase", actor))
|
if (LUA_CallAction("A_SPBChase", actor))
|
||||||
return;
|
return;
|
||||||
#endif
|
#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;
|
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))
|
if (!S_SoundPlaying(actor, actor->info->activesound))
|
||||||
S_StartSound(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);
|
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);
|
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
|
||||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
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));
|
// Smoothly rotate horz angle
|
||||||
actor->momz = FixedMul(maxspeed, FINESINE(vang>>ANGLETOFINESHIFT));
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else // Target's gone, return to SEEKING
|
||||||
{
|
{
|
||||||
P_SetTarget(&actor->tracer, NULL);
|
P_SetTarget(&actor->tracer, NULL);
|
||||||
actor->extravalue1 = 0;
|
actor->extravalue1 = 0; // Find someone new next tic
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // MODE: SEEKING
|
||||||
|
{
|
||||||
|
// Find the player with the best rank
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i])
|
if (!playeringame[i] || players[i].spectator || players[i].exiting)
|
||||||
continue;
|
continue; // not in-game
|
||||||
|
|
||||||
if (players[i].spectator)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].exiting)
|
|
||||||
continue; // exiting
|
|
||||||
|
|
||||||
if (!players[i].mo)
|
if (!players[i].mo)
|
||||||
continue; // no mobj
|
continue; // no mobj
|
||||||
|
@ -8383,6 +8430,9 @@ void A_SPBChase(mobj_t *actor)
|
||||||
if (players[i].mo->health <= 0)
|
if (players[i].mo->health <= 0)
|
||||||
continue; // dead
|
continue; // dead
|
||||||
|
|
||||||
|
if (players[i].kartstuff[k_respawn])
|
||||||
|
continue; // respawning
|
||||||
|
|
||||||
if (players[i].kartstuff[k_position] < bestrank)
|
if (players[i].kartstuff[k_position] < bestrank)
|
||||||
{
|
{
|
||||||
bestrank = players[i].kartstuff[k_position];
|
bestrank = players[i].kartstuff[k_position];
|
||||||
|
@ -8390,24 +8440,58 @@ void A_SPBChase(mobj_t *actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player != NULL && player->mo)
|
// 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);
|
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);
|
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);
|
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
|
||||||
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);
|
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);
|
// Smoothly rotate horz angle
|
||||||
actor->extravalue1 = 1;
|
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;
|
mobj_t *spbexplode;
|
||||||
|
|
||||||
|
S_StopSound(special); // Don't continue playing the gurgle or the siren
|
||||||
|
|
||||||
if (!player->kartstuff[k_invincibilitytimer] && !player->kartstuff[k_growshrinktimer])
|
if (!player->kartstuff[k_invincibilitytimer] && !player->kartstuff[k_growshrinktimer])
|
||||||
{
|
{
|
||||||
K_DropHnextList(player);
|
K_DropHnextList(player);
|
||||||
K_StripItems(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);
|
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)
|
if (mobj->threshold > 0)
|
||||||
mobj->threshold--;
|
mobj->threshold--;
|
||||||
break;
|
break;
|
||||||
case MT_BALLHOG:
|
|
||||||
case MT_SPB:
|
case MT_SPB:
|
||||||
|
indirectitemcooldown = 20*TICRATE;
|
||||||
|
/* FALLTHRU */
|
||||||
|
case MT_BALLHOG:
|
||||||
P_SpawnGhostMobj(mobj)->fuse = 3;
|
P_SpawnGhostMobj(mobj)->fuse = 3;
|
||||||
if (mobj->threshold > 0)
|
if (mobj->threshold > 0)
|
||||||
mobj->threshold--;
|
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);
|
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!
|
if (mo == inflictor) // Don't nuke yourself, dummy!
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue