WIP amp visuals

This commit is contained in:
Antonio Martinez 2025-06-11 23:45:18 -04:00
parent f5c2031ea5
commit a0cc5dc69a
11 changed files with 196 additions and 2 deletions

View file

@ -2686,6 +2686,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
"S_EGOORB",
"S_AMPS",
"S_EXP",
"S_WATERTRAIL1",
"S_WATERTRAIL2",
@ -4009,6 +4010,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_PULLUPHOOK",
"MT_AMPS",
"MT_EXP",
"MT_FLYBOT767",

View file

@ -600,6 +600,8 @@ char sprnames[NUMSPRITES + 1][5] =
"AMPC",
"AMPD",
"EXPC",
"SOR_",
"WTRL", // Water Trail
@ -3246,6 +3248,7 @@ state_t states[NUMSTATES] =
{SPR_EGOO, 0, 1, {NULL}, 0, 0, S_NULL}, // S_EGOORB
{SPR_AMPA, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 41, 1, S_NULL}, // S_AMPS
{SPR_EXPC, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_EXP
// Water Trail
{SPR_WTRL, FF_PAPERSPRITE , 2, {NULL}, 0, 0, S_NULL}, // S_WATERTRAIL1
@ -22482,7 +22485,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate
},
{ // MT_AMPS
3444, // doomednum
-1, // doomednum
S_AMPS, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
@ -22507,6 +22510,32 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_NOCLIPTHING, // flags
S_NULL // raisestate
},
{ // MT_EXP
-1, // doomednum
S_EXP, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
1, // speed
32*FRACUNIT, // radius
32*FRACUNIT, // height
0, // dispoffset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP|MF_NOCLIPTHING, // flags
S_NULL // raisestate
},
{ // MT_FLYBOT767
-1, // doomednum
S_FLYBOT767, // spawnstate

View file

@ -1141,6 +1141,8 @@ typedef enum sprite
SPR_AMPC,
SPR_AMPD,
SPR_EXPC,
SPR_SOR_,
SPR_WTRL, // Water Trail
@ -3742,6 +3744,7 @@ typedef enum state
S_EGOORB,
S_AMPS,
S_EXP,
S_WATERTRAIL1,
S_WATERTRAIL2,
@ -5091,6 +5094,7 @@ typedef enum mobj_type
MT_PULLUPHOOK,
MT_AMPS,
MT_EXP,
MT_FLYBOT767,

View file

@ -4229,6 +4229,25 @@ void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact)
}
}
void K_SpawnEXP(player_t *player, UINT8 exp, mobj_t *impact)
{
if (exp == 0)
return;
for (int i = 0; i < exp; i++)
{
mobj_t *pickup = P_SpawnMobj(impact->x, impact->y, impact->z, MT_EXP);
pickup->momx = impact->momx;
pickup->momy = impact->momy;
pickup->momz = impact->momz;
pickup->momx += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
pickup->momy += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
pickup->momz += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
// pickup->color = player->skincolor;
P_SetTarget(&pickup->target, player->mo);
}
}
void K_AwardPlayerAmps(player_t *player, UINT8 amps)
{
UINT16 getamped = player->amps + amps;

View file

@ -159,6 +159,7 @@ angle_t K_MomentumAngleReal(const mobj_t *mo);
#define K_MomentumAngle(mo) K_MomentumAngleEx(mo, 6 * mo->scale)
boolean K_PvPAmpReward(UINT32 award, player_t *attacker, player_t *defender);
void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact);
void K_SpawnEXP(player_t *player, UINT8 exp, mobj_t *impact);
void K_AwardPlayerAmps(player_t *player, UINT8 amps);
void K_CheckpointCrossAward(player_t *player);
void K_AwardPlayerRings(player_t *player, UINT16 rings, boolean overload);

View file

@ -146,6 +146,8 @@ void Obj_AmpBurstThink(mobj_t *amp);
void Obj_AmpsThink(mobj_t *amps);
void Obj_ExpThink(mobj_t *exp);
void Obj_ChargeAuraThink(mobj_t *aura);
void Obj_ChargeFallThink(mobj_t *charge);
void Obj_ChargeReleaseThink(mobj_t *release);

View file

@ -65,6 +65,7 @@ target_sources(SRB2SDL2 PRIVATE
lightning-shield.cpp
flame-shield.cpp
stone-shoe.cpp
exp.c
)
add_subdirectory(versus)

View file

@ -688,8 +688,17 @@ void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
player->checkpointId = chk->id();
UINT16 oldexp = player->exp;
K_CheckpointCrossAward(player);
if (player->exp > oldexp)
{
UINT16 expdiff = (player->exp - oldexp);
K_SpawnEXP(player, expdiff, chk);
K_SpawnEXP(player, expdiff, chk->other());
}
K_UpdatePowerLevels(player, player->laps, false);
}

122
src/objects/exp.c Normal file
View file

@ -0,0 +1,122 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by AJ "Tyron" Martinez.
// Copyright (C) 2025 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 amps.c
/// \brief EXP 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"
#include "../r_main.h"
#include "../m_easing.h"
#include "../s_sound.h"
#include "../sounds.h"
#define EXP_ARCTIME (8)
#define EXP_ORBIT (240)
#define EXP_COLLECT (100)
void Obj_ExpThink (mobj_t *exp)
{
if (P_MobjWasRemoved(exp->target)
|| exp->target->health == 0
|| exp->target->destscale <= 1 // sealed star fall out
|| !exp->target->player)
{
P_RemoveMobj(exp);
}
else
{
mobj_t *mo = exp->target;
player_t *player = mo->player;
fixed_t dist, fakez;
angle_t hang, vang;
dist = P_AproxDistance(P_AproxDistance(exp->x - mo->x, exp->y - mo->y), exp->z - mo->z);
exp->angle += ANGLE_45/4;
if (exp->threshold)
{
A_AttractChase(exp);
exp->threshold = min(exp->threshold, 1);
dist = P_AproxDistance(P_AproxDistance(exp->x - mo->x, exp->y - mo->y), exp->z - mo->z);
if (dist < (EXP_COLLECT * exp->scale))
P_RemoveMobj(exp);
return;
}
UINT8 damper = 3;
fixed_t vert = dist/3;
fixed_t speed = 45*exp->scale;
exp->cusval++;
if (exp->extravalue2) // Mode: going down, aim at the player and speed up / dampen stray movement
{
if (exp->extravalue1)
exp->extravalue1--;
exp->extravalue2++;
speed += exp->extravalue2 * exp->scale/2;
fakez = mo->z + (vert * exp->extravalue1 / EXP_ARCTIME);
damper = 1;
}
else // Mode: going up, aim above the player
{
exp->extravalue1++;
if (exp->extravalue1 >= EXP_ARCTIME)
exp->extravalue2 = 1;
fakez = mo->z + vert;
}
if (mo->flags & MFE_VERTICALFLIP)
fakez -= mo->height/2;
else
fakez += mo->height/2;
hang = R_PointToAngle2(exp->x, exp->y, mo->x, mo->y);
vang = R_PointToAngle2(exp->z, 0, fakez, dist);
exp->momx -= exp->momx>>(damper), exp->momy -= exp->momy>>(damper), exp->momz -= exp->momz>>(damper);
exp->momx += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(hang>>ANGLETOFINESHIFT), speed));
exp->momy += FixedMul(FINESINE(vang>>ANGLETOFINESHIFT), FixedMul(FINESINE(hang>>ANGLETOFINESHIFT), speed));
exp->momz += FixedMul(FINECOSINE(vang>>ANGLETOFINESHIFT), speed);
if (exp->cusval%2)
{
mobj_t *ghost = P_SpawnGhostMobj(exp);
ghost->colorized = true;
ghost->color = player->skincolor;
ghost->renderflags |= RF_ADD;
ghost->fuse = 1;
}
if (dist < (EXP_ORBIT * exp->scale) && exp->extravalue2)
{
P_SetTarget(&exp->tracer, exp->target);
exp->threshold = TICRATE;
exp->extravalue1 = 0;
exp->extravalue2 = 0;
}
}
}

View file

@ -3501,7 +3501,7 @@ void A_AttractChase(mobj_t *actor)
if (actor->flags2 & MF2_NIGHTSPULL || !actor->health)
return;
if (actor->extravalue1 && actor->type != MT_EMERALD) // SRB2Kart
if (actor->extravalue1 && actor->type != MT_EMERALD && actor->type != MT_EXP) // SRB2Kart
{
if (!actor->target || P_MobjWasRemoved(actor->target) || !actor->target->player)
{

View file

@ -8908,6 +8908,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
Obj_AmpsThink(mobj);
break;
}
case MT_EXP:
{
Obj_ExpThink(mobj);
break;
}
case MT_BLOCKRING:
{
Obj_BlockRingThink(mobj);