mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
- Quake epicenter + radius now work. - Since quake epicenter works, removed the display player check on all of the quakes, so other players can feel them. - Multiple quake effects are stored in a linked list and dynamically created/freed, so they can stack together. - Made in china - Made the quake effects only work on the z axis. - Quakes now alternate their intensity and dampen it over time, instead of randomly picking values. - Added quake effects for offroad and stair-jank - Disabled quakes in reducevfx - Removed actionmovie and windowquake (sorry jartha)
304 lines
6.2 KiB
C
304 lines
6.2 KiB
C
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
|
// Copyright (C) 2022 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 manta-ring.c
|
|
/// \brief SPB Juicebox rings. See spb.c for their spawning.
|
|
|
|
#include "../doomdef.h"
|
|
#include "../doomstat.h"
|
|
#include "../info.h"
|
|
#include "../k_kart.h"
|
|
#include "../k_objects.h"
|
|
#include "../m_random.h"
|
|
#include "../p_local.h"
|
|
#include "../r_main.h"
|
|
#include "../s_sound.h"
|
|
#include "../g_game.h"
|
|
#include "../z_zone.h"
|
|
#include "../k_waypoint.h"
|
|
#include "../k_respawn.h"
|
|
|
|
#define MANTA_RACETIME (90)
|
|
#define MANTA_MINTIME (15)
|
|
#define MANTA_SPRINTTIME (60)
|
|
|
|
#define MANTA_ALIVEGATE (0)
|
|
#define MANTA_DEADGATE (FF_TRANS80)
|
|
|
|
#define MANTA_SIZE (2 * FRACUNIT)
|
|
#define MANTA_SIZEUP (10)
|
|
#define MANTA_SIZESTRENGTH (1500)
|
|
#define MANTA_MAXRAMP (80)
|
|
|
|
#define MANTA_COLLIDE (80 * FRACUNIT)
|
|
|
|
#define MANTA_TURBO (40)
|
|
#define MANTA_FASTRAMP (17)
|
|
#define MANTA_MINPWR (10)
|
|
|
|
#define manta_delay(o) ((o)->fuse)
|
|
#define manta_timealive(o) ((o)->movecount)
|
|
#define manta_boostval(o) ((o)->extravalue1)
|
|
#define manta_laps(o) ((o)->extravalue2)
|
|
#define manta_touched(o) ((o)->cusval)
|
|
|
|
#define manta_owner(o) ((o)->target)
|
|
#define manta_chase(o) ((o)->tracer)
|
|
|
|
static boolean MantaAlreadyTouched(mobj_t *manta, player_t *player)
|
|
{
|
|
INT32 touchFlag = 0;
|
|
|
|
if (manta_chase(manta) != NULL && P_MobjWasRemoved(manta_chase(manta)) == false
|
|
&& player->mo == manta_chase(manta))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
#if 0
|
|
if (manta_laps(manta) < player->laps)
|
|
{
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
touchFlag = 1 << (player - players);
|
|
return (manta_touched(manta) & touchFlag);
|
|
}
|
|
|
|
static void Obj_MantaCollide(mobj_t *manta, mobj_t *other)
|
|
{
|
|
// Could hook this into actual mobj collide if desired.
|
|
fixed_t distance = INT32_MAX;
|
|
fixed_t size = INT32_MAX;
|
|
|
|
INT32 addBoost = 0;
|
|
INT32 touchFlag = 0;
|
|
|
|
size_t i;
|
|
|
|
distance = P_AproxDistance(P_AproxDistance(
|
|
other->x - manta->x,
|
|
other->y - manta->y),
|
|
other->z - manta->z) - other->radius - manta->radius;
|
|
|
|
size = FixedMul(MANTA_COLLIDE, mapobjectscale);
|
|
|
|
if (distance > size)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (other->player != NULL) // Just in case other objects should be added?
|
|
{
|
|
if (MantaAlreadyTouched(manta, other->player))
|
|
{
|
|
return;
|
|
}
|
|
|
|
touchFlag = 1 << (other->player - players);
|
|
}
|
|
|
|
addBoost = manta_boostval(manta);
|
|
|
|
if (manta_timealive(manta) < MANTA_FASTRAMP)
|
|
{
|
|
// Ramp up to max power.
|
|
addBoost = FixedMul(addBoost * FRACUNIT, (manta_timealive(manta) * FRACUNIT) / MANTA_FASTRAMP);
|
|
|
|
// Convert to integer
|
|
addBoost = (addBoost + (FRACUNIT/2)) / FRACUNIT;
|
|
|
|
// Cap it
|
|
addBoost = max(MANTA_MINPWR, addBoost);
|
|
}
|
|
|
|
if (other->player != NULL)
|
|
{
|
|
UINT8 snd = 0;
|
|
|
|
if (other->player->speedboost > FRACUNIT/4)
|
|
{
|
|
snd = other->player->gateSound;
|
|
other->player->gateSound++;
|
|
|
|
if (other->player->gateSound > 4)
|
|
{
|
|
other->player->gateSound = 4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
other->player->gateSound = 0;
|
|
}
|
|
|
|
K_SpawnDriftBoostExplosion(other->player, 3);
|
|
K_SpawnDriftElectricSparks(other->player, SKINCOLOR_CRIMSON, true);
|
|
|
|
for (i = 0; i < 5; i++)
|
|
{
|
|
S_StopSoundByID(other, sfx_gate01 + i);
|
|
}
|
|
|
|
S_StartSound(other, sfx_gate01 + snd);
|
|
other->player->gateBoost += addBoost/2;
|
|
|
|
P_StartQuakeFromMobj(6, 12 * other->scale, 512 * other->scale, other);
|
|
}
|
|
|
|
if (touchFlag > 0)
|
|
{
|
|
manta_touched(manta) |= touchFlag;
|
|
}
|
|
}
|
|
|
|
static void RunMantaCollide(mobj_t *manta)
|
|
{
|
|
INT32 i;
|
|
|
|
for (i = 0; i < MAXPLAYERS; i++)
|
|
{
|
|
player_t *player = NULL;
|
|
|
|
if (playeringame[i] == false)
|
|
{
|
|
// Invalid
|
|
continue;
|
|
}
|
|
|
|
player = &players[i];
|
|
if (player->spectator == true)
|
|
{
|
|
// Not playing.
|
|
continue;
|
|
}
|
|
|
|
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
|
|
{
|
|
// Invalid object
|
|
continue;
|
|
}
|
|
|
|
if (player->mo == manta_chase(manta))
|
|
{
|
|
// Don't allow the person being chased to touch this.
|
|
continue;
|
|
}
|
|
|
|
Obj_MantaCollide(manta, player->mo);
|
|
}
|
|
}
|
|
|
|
static void RunMantaVisual(mobj_t *manta)
|
|
{
|
|
INT32 i;
|
|
|
|
if (manta->fuse < 5*TICRATE)
|
|
{
|
|
if (leveltime & 1)
|
|
{
|
|
manta->renderflags |= RF_DONTDRAW;
|
|
}
|
|
else
|
|
{
|
|
manta->renderflags &= ~RF_DONTDRAW;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i <= r_splitscreen; i++)
|
|
{
|
|
const UINT8 pID = displayplayers[i];
|
|
player_t *player = &players[pID];
|
|
|
|
if (MantaAlreadyTouched(manta, player) == false)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i > r_splitscreen)
|
|
{
|
|
manta->frame = (manta->frame & ~FF_TRANSMASK) | MANTA_DEADGATE;
|
|
}
|
|
else
|
|
{
|
|
manta->frame = (manta->frame & ~FF_TRANSMASK) | MANTA_ALIVEGATE;
|
|
}
|
|
}
|
|
|
|
void Obj_MantaRingThink(mobj_t *manta)
|
|
{
|
|
RunMantaVisual(manta);
|
|
|
|
if (manta_delay(manta) % MANTA_SIZEUP == 0)
|
|
{
|
|
manta->destscale += FixedMul(MANTA_SIZESTRENGTH, mapobjectscale);
|
|
manta_boostval(manta) = min(MANTA_MAXRAMP, manta_boostval(manta) + 1);
|
|
}
|
|
|
|
manta_timealive(manta)++;
|
|
|
|
RunMantaCollide(manta);
|
|
}
|
|
|
|
mobj_t *Obj_MantaRingCreate(mobj_t *spb, mobj_t *owner, mobj_t *chase)
|
|
{
|
|
mobj_t *manta = NULL;
|
|
INT32 delay = 0;
|
|
|
|
manta = P_SpawnMobjFromMobj(spb, 0, 0, 0, MT_MANTARING);
|
|
|
|
manta->color = SKINCOLOR_KETCHUP;
|
|
|
|
manta->destscale = FixedMul(MANTA_SIZE, spb->scale);
|
|
P_SetScale(manta, manta->destscale);
|
|
|
|
manta->angle = R_PointToAngle2(0, 0, spb->momx, spb->momy) + ANGLE_90;
|
|
|
|
// Set boost value
|
|
manta_boostval(manta) = MANTA_TURBO;
|
|
|
|
// Set despawn delay
|
|
delay = max(MANTA_MINTIME, MANTA_RACETIME / mapheaderinfo[gamemap - 1]->numlaps);
|
|
|
|
if (mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
|
{
|
|
delay = MANTA_SPRINTTIME;
|
|
}
|
|
|
|
manta_delay(manta) = delay * TICRATE;
|
|
|
|
// Default if neither object exists
|
|
manta_laps(manta) = INT32_MAX;
|
|
|
|
// Set owner
|
|
if (owner != NULL && P_MobjWasRemoved(owner) == false)
|
|
{
|
|
P_SetTarget(&manta_owner(manta), owner);
|
|
|
|
if (owner->player != NULL)
|
|
{
|
|
// Default if chaser doesn't exist
|
|
manta_laps(manta) = owner->player->laps;
|
|
}
|
|
}
|
|
|
|
// Set chaser
|
|
if (chase != NULL && P_MobjWasRemoved(chase) == false)
|
|
{
|
|
P_SetTarget(&manta_chase(manta), chase);
|
|
|
|
if (chase->player != NULL)
|
|
{
|
|
manta_laps(manta) = chase->player->laps;
|
|
}
|
|
}
|
|
|
|
return manta;
|
|
}
|