mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
159 lines
No EOL
5.1 KiB
C
159 lines
No EOL
5.1 KiB
C
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2024 by AJ "Tyron" Martinez.
|
|
// Copyright (C) 2024 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 charge.c
|
|
/// \brief Charge VFX code.
|
|
|
|
#include "../doomdef.h"
|
|
#include "../info.h"
|
|
#include "../k_objects.h"
|
|
#include "../p_local.h"
|
|
#include "../k_kart.h"
|
|
#include "../k_powerup.h"
|
|
#include "../m_random.h"
|
|
|
|
#define CHARGEAURA_BURSTTIME (9)
|
|
#define CHARGEAURA_SPARKRADIUS (40)
|
|
|
|
// xval1: destruction timer
|
|
// xval2: master (spawns other visuals)
|
|
// cvmem: spawn time (used to offset flash)
|
|
void Obj_ChargeAuraThink (mobj_t *aura)
|
|
{
|
|
if (P_MobjWasRemoved(aura->target) || !aura->target->player || (aura->extravalue1 >= CHARGEAURA_BURSTTIME))
|
|
{
|
|
P_RemoveMobj(aura);
|
|
}
|
|
else
|
|
{
|
|
mobj_t *mo = aura->target;
|
|
player_t *player = mo->player;
|
|
|
|
// Follow player
|
|
aura->flags &= ~(MF_NOCLIPTHING);
|
|
P_MoveOrigin(aura, mo->x, mo->y, mo->z + mo->height/2);
|
|
aura->flags |= MF_NOCLIPTHING;
|
|
aura->color = mo->color;
|
|
|
|
aura->renderflags &= ~RF_DONTDRAW;
|
|
|
|
fixed_t baseScale = 12*mo->scale/10;
|
|
|
|
if (aura->extravalue1 || !player->trickcharge)
|
|
{
|
|
aura->extravalue1++;
|
|
baseScale += (mo->scale / 3) * aura->extravalue1;
|
|
aura->renderflags &= ~RF_TRANSMASK;
|
|
aura->renderflags |= (aura->extravalue1)<<RF_TRANSSHIFT;
|
|
if (aura->extravalue1 % 2)
|
|
aura->renderflags |= RF_DONTDRAW;
|
|
}
|
|
|
|
P_SetScale(aura, baseScale);
|
|
|
|
// Twirl
|
|
aura->angle = aura->angle - ANG1*(player->trickcharge/TICRATE + 4);
|
|
// Visuals
|
|
aura->renderflags |= RF_PAPERSPRITE|RF_ADD;
|
|
|
|
// fuck
|
|
boolean forceinvisible = !!!((leveltime - aura->cvmem) % 4);
|
|
if (aura->extravalue1 || !(player->driftcharge > K_GetKartDriftSparkValueForStage(player, 3)))
|
|
forceinvisible = false;
|
|
|
|
if (forceinvisible)
|
|
aura->renderflags |= RF_DONTDRAW;
|
|
|
|
if (aura->extravalue2)
|
|
{
|
|
if (player->driftcharge)
|
|
{
|
|
mobj_t *spark = P_SpawnMobjFromMobj(aura,
|
|
FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS),
|
|
FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS),
|
|
FRACUNIT*P_RandomRange(PR_DECORATION, -1*CHARGEAURA_SPARKRADIUS, CHARGEAURA_SPARKRADIUS),
|
|
MT_CHARGESPARK);
|
|
spark->frame = P_RandomRange(PR_DECORATION, 1, 5);
|
|
spark->renderflags |= RF_FULLBRIGHT|RF_ADD;
|
|
P_SetTarget(&spark->target, aura);
|
|
P_SetScale(spark, 15*aura->scale/10);
|
|
}
|
|
|
|
if (forceinvisible)
|
|
{
|
|
mobj_t *flicker = P_SpawnMobjFromMobj(aura, 0, 0, 0, MT_CHARGEFLICKER);
|
|
P_SetTarget(&flicker->target, aura);
|
|
P_SetScale(flicker, aura->scale);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Obj_ChargeFallThink (mobj_t *charge)
|
|
{
|
|
if (P_MobjWasRemoved(charge->target) || !charge->target->player)
|
|
{
|
|
P_RemoveMobj(charge);
|
|
}
|
|
else
|
|
{
|
|
mobj_t *mo = charge->target;
|
|
|
|
// Follow player
|
|
charge->flags &= ~(MF_NOCLIPTHING);
|
|
P_MoveOrigin(charge, mo->x, mo->y, mo->z);
|
|
charge->flags |= MF_NOCLIPTHING;
|
|
charge->color = mo->color;
|
|
charge->angle = mo->angle + ANGLE_45 + (ANGLE_90 * charge->extravalue1);
|
|
|
|
if (!P_IsObjectOnGround(mo))
|
|
charge->renderflags |= RF_DONTDRAW;
|
|
else
|
|
charge->renderflags &= ~RF_DONTDRAW;
|
|
|
|
fixed_t baseScale = 12*mo->scale/10;
|
|
P_SetScale(charge, baseScale);
|
|
|
|
charge->renderflags &= ~RF_TRANSMASK;
|
|
if (charge->tics < 10)
|
|
charge->renderflags |= (9 - charge->tics)<<RF_TRANSSHIFT;
|
|
|
|
// Visuals
|
|
charge->renderflags |= RF_PAPERSPRITE|RF_ADD;
|
|
}
|
|
}
|
|
|
|
// xval1: lifetime (used to offset from tracked player)
|
|
void Obj_ChargeReleaseThink (mobj_t *release)
|
|
{
|
|
release->renderflags &= ~RF_TRANSMASK;
|
|
if (release->tics < 36)
|
|
release->renderflags |= (9 - release->tics/4)<<RF_TRANSSHIFT;
|
|
release->rollangle += ANG15/2;
|
|
|
|
if (P_MobjWasRemoved(release->target) || !release->target->player)
|
|
return;
|
|
|
|
release->extravalue1++;
|
|
|
|
fixed_t off = 8 * release->extravalue1 * release->target->scale;
|
|
angle_t ang = K_MomentumAngle(release->target) + ANGLE_180;
|
|
fixed_t xoff = FixedMul(off, FINECOSINE(ang >> ANGLETOFINESHIFT));
|
|
fixed_t yoff = FixedMul(off, FINESINE(ang >> ANGLETOFINESHIFT));
|
|
|
|
P_MoveOrigin(release, release->target->x + xoff, release->target->y + yoff, release->target->z + release->target->height/2);
|
|
}
|
|
|
|
void Obj_ChargeExtraThink (mobj_t *extra)
|
|
{
|
|
extra->renderflags &= ~RF_TRANSMASK;
|
|
if (extra->tics < 18)
|
|
extra->renderflags |= (9 - extra->tics/2)<<RF_TRANSSHIFT;
|
|
extra->rollangle += ANG30;
|
|
} |