mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 20:41:46 +00:00
Rideroid: first pass
This commit is contained in:
parent
56d8ae67ae
commit
aef958d7ed
6 changed files with 530 additions and 1 deletions
|
|
@ -4669,6 +4669,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
||||||
"S_CHECKPOINT_SPARK9",
|
"S_CHECKPOINT_SPARK9",
|
||||||
"S_CHECKPOINT_SPARK10",
|
"S_CHECKPOINT_SPARK10",
|
||||||
"S_CHECKPOINT_SPARK11",
|
"S_CHECKPOINT_SPARK11",
|
||||||
|
|
||||||
|
"S_RIDEROID",
|
||||||
|
"S_RIDEROID_ICON",
|
||||||
};
|
};
|
||||||
|
|
||||||
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
|
// RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1",
|
||||||
|
|
@ -5821,6 +5824,9 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
|
||||||
|
|
||||||
"MT_CHECKPOINT_END",
|
"MT_CHECKPOINT_END",
|
||||||
"MT_SCRIPT_THING",
|
"MT_SCRIPT_THING",
|
||||||
|
|
||||||
|
"MT_RIDEROID",
|
||||||
|
"MT_RIDEROIDNODE",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *const MOBJFLAG_LIST[] = {
|
const char *const MOBJFLAG_LIST[] = {
|
||||||
|
|
|
||||||
|
|
@ -30439,7 +30439,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // mass
|
0, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_NOGRAVITY, // flags
|
MF_NOGRAVITY|MF_NOCLIP, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,13 @@ boolean Obj_GetCheckpointRespawnPosition(const mobj_t *checkpoint, vector3_t *re
|
||||||
angle_t Obj_GetCheckpointRespawnAngle(const mobj_t *checkpoint);
|
angle_t Obj_GetCheckpointRespawnAngle(const mobj_t *checkpoint);
|
||||||
void Obj_ActivateCheckpointInstantly(mobj_t* mobj);
|
void Obj_ActivateCheckpointInstantly(mobj_t* mobj);
|
||||||
|
|
||||||
|
/* Rideroid / Rideroid Node */
|
||||||
|
void Obj_RideroidThink(mobj_t *mo);
|
||||||
|
|
||||||
|
void Obj_RideroidNodeSpawn(mobj_t *mo);
|
||||||
|
void Obj_RideroidNodeThink(mobj_t *mo);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,5 @@ target_sources(SRB2SDL2 PRIVATE
|
||||||
sneaker-panel.c
|
sneaker-panel.c
|
||||||
emerald.c
|
emerald.c
|
||||||
checkpoint.cpp
|
checkpoint.cpp
|
||||||
|
rideroid.c
|
||||||
)
|
)
|
||||||
|
|
|
||||||
498
src/objects/rideroid.c
Normal file
498
src/objects/rideroid.c
Normal file
|
|
@ -0,0 +1,498 @@
|
||||||
|
// 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 rideroid.c
|
||||||
|
/// \brief Rideroid / Rideroid Node object code. This also has the player behaviour code to be used in k_kart.
|
||||||
|
|
||||||
|
#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"
|
||||||
|
#include "../k_collide.h"
|
||||||
|
|
||||||
|
#define NODERADIUS 260
|
||||||
|
#define NODEPULLOK 16
|
||||||
|
#define NODEROTSPEED ANG1
|
||||||
|
|
||||||
|
#define RIDEROIDSPEED 80
|
||||||
|
#define RIDEROIDMAXADD 8
|
||||||
|
|
||||||
|
|
||||||
|
// static functions that only really get used here...
|
||||||
|
static void plr_undoRespawn(player_t *p)
|
||||||
|
{
|
||||||
|
p->respawn.state = 0;
|
||||||
|
p->respawn.timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void plr_resetRideroidVars(player_t *p)
|
||||||
|
{
|
||||||
|
p->rdnodepull = false;
|
||||||
|
p->rideroid = false;
|
||||||
|
p->rideroidangle = 0;
|
||||||
|
p->rideroidspeed = 0;
|
||||||
|
p->rideroidrollangle = 0;
|
||||||
|
|
||||||
|
p->rdaddmomx = 0;
|
||||||
|
p->rdaddmomy = 0;
|
||||||
|
p->rdaddmomz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// kills the rideroid and removes it from the map.
|
||||||
|
static void Obj_killRideroid(mobj_t *mo)
|
||||||
|
{
|
||||||
|
P_RemoveMobj(mo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this assumes mo->target and mo->target->player is valid.
|
||||||
|
// if it's not, uuuh well too bad.
|
||||||
|
static void Obj_getPlayerOffRideroid(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *pmo = mo->target;
|
||||||
|
player_t *p = pmo->player;
|
||||||
|
|
||||||
|
pmo->flags &= ~MF_NOGRAVITY;
|
||||||
|
plr_resetRideroidVars(p);
|
||||||
|
|
||||||
|
if (!P_MobjWasRemoved(mo))
|
||||||
|
mo->fuse = TICRATE/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this assumes mo->target and mo->target->player is valid.
|
||||||
|
// if it's not, uuuh well too bad.
|
||||||
|
static void Obj_explodeRideroid(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *pmo = mo->target;
|
||||||
|
|
||||||
|
Obj_getPlayerOffRideroid(mo);
|
||||||
|
K_SpawnMineExplosion(pmo, pmo->color, 3);
|
||||||
|
S_StartSound(pmo, sfx_s3k4e);
|
||||||
|
Obj_killRideroid(mo);
|
||||||
|
|
||||||
|
// @TODO: quake.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to create a smooth trail.
|
||||||
|
static fixed_t Obj_rideroidLerp(INT32 start, INT32 finish, INT32 percent)
|
||||||
|
{
|
||||||
|
return start + FixedMul(finish-start, FRACUNIT-percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Obj_rideroidTrail(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *pmo = mo->target;
|
||||||
|
player_t *p = pmo->player; // used to make some graphics local to save on framerate
|
||||||
|
|
||||||
|
UINT8 i, j;
|
||||||
|
|
||||||
|
angle_t h_an = mo->angle + ANG1*90;
|
||||||
|
// from here, we will use the following:
|
||||||
|
// extravalue1: prev x
|
||||||
|
// extravalue2: prev y
|
||||||
|
// cusval: prev z
|
||||||
|
// cvmem: prev roll angle
|
||||||
|
|
||||||
|
mo->color = pmo->color;
|
||||||
|
mo->colorized = pmo->colorized;
|
||||||
|
|
||||||
|
for (j = 0; j < 9; j++)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
INT32 percent = FRACUNIT * (10-j)/10;
|
||||||
|
angle_t roll = (angle_t)Obj_rideroidLerp((angle_t)mo->cvmem, mo->rollangle, percent);
|
||||||
|
fixed_t x = (fixed_t)Obj_rideroidLerp((fixed_t)mo->extravalue1, mo->x, percent);
|
||||||
|
fixed_t y = (fixed_t)Obj_rideroidLerp((fixed_t)mo->extravalue2, mo->y, percent);
|
||||||
|
fixed_t z = (fixed_t)Obj_rideroidLerp((fixed_t)mo->cusval, mo->z, percent);
|
||||||
|
|
||||||
|
angle_t v_an = i ? (roll+ANG1*90) : (roll-ANG1*90);
|
||||||
|
|
||||||
|
fixed_t pos = FixedMul(mo->scale, FINESINE(v_an>>ANGLETOFINESHIFT)*60);
|
||||||
|
fixed_t tx = x+FixedMul(FINECOSINE(h_an>>ANGLETOFINESHIFT), pos);
|
||||||
|
fixed_t ty = y+FixedMul(FINESINE(h_an>>ANGLETOFINESHIFT), pos);
|
||||||
|
fixed_t tz = z+FixedMul(FINECOSINE(v_an>>ANGLETOFINESHIFT)*60, mo->scale);
|
||||||
|
|
||||||
|
mobj_t *t = P_SpawnMobj(tx, ty, tz, MT_THOK);
|
||||||
|
t->color = SKINCOLOR_TEAL;
|
||||||
|
t->frame = FF_FULLBRIGHT|FF_TRANS50;
|
||||||
|
// 120 is no magic number, the base scale speed is mapobjectscale/12
|
||||||
|
P_SetScale(t, max(1, mapobjectscale*5/6 - ((10-j)*mapobjectscale/120)));
|
||||||
|
t->destscale = 1;
|
||||||
|
|
||||||
|
if (p != &players[consoleplayer] && j)
|
||||||
|
t->renderflags |= RF_DONTDRAW;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mo->extravalue1 = (INT32)mo->x;
|
||||||
|
mo->extravalue2 = (INT32)mo->y;
|
||||||
|
mo->cusval = (INT32)mo->z;
|
||||||
|
mo->cvmem = (INT32)mo->rollangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Obj_updateRideroidPos(mobj_t *mo)
|
||||||
|
{
|
||||||
|
mobj_t *pmo = mo->target;
|
||||||
|
|
||||||
|
fixed_t x = pmo->x + 2*FINECOSINE(pmo->angle>>ANGLETOFINESHIFT);
|
||||||
|
fixed_t y = pmo->y + 2*FINESINE(pmo->angle>>ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
P_MoveOrigin(mo, x, y, pmo->z - 10*mapobjectscale);
|
||||||
|
Obj_rideroidTrail(mo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles the rideroid and the player attached to it.
|
||||||
|
void Obj_RideroidThink(mobj_t *mo)
|
||||||
|
{
|
||||||
|
player_t *p;
|
||||||
|
mobj_t *pmo = mo->target;
|
||||||
|
|
||||||
|
fixed_t basemomx;
|
||||||
|
fixed_t basemomy;
|
||||||
|
fixed_t xthreshold;
|
||||||
|
fixed_t ythreshold;
|
||||||
|
|
||||||
|
|
||||||
|
// speed values...
|
||||||
|
fixed_t maxspd = RIDEROIDSPEED*mapobjectscale;
|
||||||
|
|
||||||
|
if (!pmo || P_MobjWasRemoved(pmo))
|
||||||
|
{
|
||||||
|
Obj_killRideroid(mo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're here, our player should still exist which is kinda crazy!
|
||||||
|
p = pmo->player;
|
||||||
|
|
||||||
|
// pulling towards the node, AKA towards where the rideroid is, which just so happens to be us right now.
|
||||||
|
if (p->rdnodepull)
|
||||||
|
{
|
||||||
|
pmo->momx = (mo->x - pmo->x)/6;
|
||||||
|
pmo->momy = (mo->y - pmo->y)/6;
|
||||||
|
pmo->momz = (mo->z - pmo->z)/6;
|
||||||
|
|
||||||
|
//CONS_Printf("%d\n", R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y)/FRACUNIT);
|
||||||
|
|
||||||
|
if (R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y) < NODEPULLOK*mapobjectscale)
|
||||||
|
{
|
||||||
|
p->rideroid = true;
|
||||||
|
p->rdnodepull = false;
|
||||||
|
|
||||||
|
//S_StartSound(pmo, sfx_ridr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we're here, we made it to the rideroid and we can use it, or something like that!
|
||||||
|
|
||||||
|
// calculate the maximum speed we can move at.
|
||||||
|
// the values are a little arbitrary but they work for how little use these have.
|
||||||
|
|
||||||
|
if (p->ringboost)
|
||||||
|
maxspd *= 12/10; // Ring Boost: 120% max speed.
|
||||||
|
|
||||||
|
if (p->draftpower)
|
||||||
|
{
|
||||||
|
UINT8 draftperc = (p->draftpower*100 / FRACUNIT); // 0-100%
|
||||||
|
maxspd += (draftperc/5) / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase speed as we go unless we're turning harshly.
|
||||||
|
if (p->rideroidspeed*mapobjectscale < maxspd)
|
||||||
|
{
|
||||||
|
if (abs(p->cmd.turning < 400))
|
||||||
|
p->rideroidspeed += (p->ringboost ? 2 : 1); // acceleration is also higher with a ring boost.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p->rideroidspeed -= 1;
|
||||||
|
|
||||||
|
|
||||||
|
// sounds
|
||||||
|
|
||||||
|
mo->movecount++; // we use this as a timer for sounds and whatnot.
|
||||||
|
|
||||||
|
//if (mo->movecount == 1 || !(mo->movecount%TICRATE))
|
||||||
|
//S_StartSound(mo, sfx_ridr3);
|
||||||
|
|
||||||
|
|
||||||
|
// aaaaand the actual gameplay and shit... wooooo
|
||||||
|
pmo->angle = mo->angle;
|
||||||
|
pmo->flags |= MF_NOGRAVITY;
|
||||||
|
|
||||||
|
// do not let the player touch the ground
|
||||||
|
// @TODO: check all 4 corners of the player and use P_GetZAt to account for slopes if pmo->standslope isn't NULL.
|
||||||
|
// right now it's not important as LV doesn't mix rdr and slopes but if somehow i manage to pull through w this shit it'll need to be done
|
||||||
|
if (pmo->eflags & MFE_VERTICALFLIP)
|
||||||
|
{
|
||||||
|
fixed_t minz = pmo->ceilingz - 2*mapobjectscale;
|
||||||
|
if (pmo->z > minz)
|
||||||
|
pmo->z = minz;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t minz = pmo->floorz + 2*mapobjectscale;
|
||||||
|
if (pmo->z < minz)
|
||||||
|
pmo->z = minz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if we hit a wall or get hit, get off of the rideroid.
|
||||||
|
if (pmo->eflags & MFE_JUSTBOUNCEDWALL || P_PlayerInPain(p))
|
||||||
|
{
|
||||||
|
Obj_explodeRideroid(mo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now actual movement:
|
||||||
|
|
||||||
|
// first, do the movement for this frame
|
||||||
|
P_InstaThrust(pmo, mo->angle, p->rideroidspeed*mapobjectscale);
|
||||||
|
pmo->momx += p->rdaddmomx;
|
||||||
|
pmo->momy += p->rdaddmomy;
|
||||||
|
pmo->momz += p->rdaddmomz;
|
||||||
|
pmo->angle = mo->angle;
|
||||||
|
p->drawangle = mo->angle;
|
||||||
|
P_SetPlayerAngle(pmo->player, mo->angle);
|
||||||
|
pmo->rollangle = p->rideroidrollangle;
|
||||||
|
mo->rollangle = p->rideroidrollangle;
|
||||||
|
pmo->pitch = 0;
|
||||||
|
|
||||||
|
// update the rideroid object (me) to be below the target player
|
||||||
|
Obj_updateRideroidPos(mo);
|
||||||
|
|
||||||
|
|
||||||
|
// now compute all the shit for the *next* frame!
|
||||||
|
basemomx = p->rideroidspeed*FINECOSINE(mo->angle >> ANGLETOFINESHIFT);
|
||||||
|
basemomy = p->rideroidspeed*FINESINE(mo->angle >> ANGLETOFINESHIFT);
|
||||||
|
|
||||||
|
// turning left/right
|
||||||
|
if (p->cmd.turning)
|
||||||
|
{
|
||||||
|
fixed_t savemomx = pmo->momx;
|
||||||
|
fixed_t savemomy = pmo->momy;
|
||||||
|
UINT8 dir = 0;
|
||||||
|
|
||||||
|
if (p->cmd.turning < -400)
|
||||||
|
{
|
||||||
|
P_Thrust(pmo, mo->angle - 90*ANG1, 2*mapobjectscale);
|
||||||
|
p->rideroidrollangle -= ANG1*3;
|
||||||
|
|
||||||
|
if (p->rideroidrollangle < -ANG1*25)
|
||||||
|
p->rideroidrollangle = -ANG1*25;
|
||||||
|
|
||||||
|
dir = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (p->cmd.turning > 400)
|
||||||
|
{
|
||||||
|
P_Thrust(pmo, mo->angle + 90*ANG1, 2*mapobjectscale);
|
||||||
|
p->rideroidrollangle += ANG1*3;
|
||||||
|
|
||||||
|
if (p->rideroidrollangle > ANG1*25)
|
||||||
|
p->rideroidrollangle = ANG1*25;
|
||||||
|
|
||||||
|
dir = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir != 0 && leveltime & 1 && p->rideroidspeed > RIDEROIDSPEED/2)
|
||||||
|
{
|
||||||
|
p->rideroidspeed -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save the added momentum
|
||||||
|
p->rdaddmomx = pmo->momx - basemomx;
|
||||||
|
p->rdaddmomy = pmo->momy - basemomy;
|
||||||
|
|
||||||
|
//CONS_Printf("CURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale);
|
||||||
|
//CONS_Printf("BASE: %d, %d\n", basemomx/mapobjectscale, basemomy/mapobjectscale);
|
||||||
|
//CONS_Printf("ADD: %d, %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale);
|
||||||
|
|
||||||
|
// find out how much addmomx and addmomy we can actually get.
|
||||||
|
// we do this by misusing P_Thrust to calc our values then immediately cancelling it.
|
||||||
|
basemomx = pmo->momx;
|
||||||
|
basemomy = pmo->momy;
|
||||||
|
P_Thrust(pmo, mo->angle - ANG1*90, RIDEROIDMAXADD*6*mapobjectscale);
|
||||||
|
xthreshold = pmo->momx - basemomx;
|
||||||
|
ythreshold = pmo->momy - basemomy;
|
||||||
|
|
||||||
|
// clamp the momentums using the calculated thresholds.
|
||||||
|
p->rdaddmomx = max(p->rdaddmomx, -abs(xthreshold));
|
||||||
|
p->rdaddmomy = max(p->rdaddmomy, -abs(ythreshold));
|
||||||
|
p->rdaddmomx = min(p->rdaddmomx, abs(xthreshold));
|
||||||
|
p->rdaddmomy = min(p->rdaddmomy, abs(ythreshold));
|
||||||
|
|
||||||
|
// now cancel it.
|
||||||
|
pmo->momx = savemomx;
|
||||||
|
pmo->momy = savemomy;
|
||||||
|
//CONS_Printf("NEWCURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale);
|
||||||
|
|
||||||
|
}
|
||||||
|
else // not turning
|
||||||
|
{
|
||||||
|
// for some reason doing *= 9/10 causes it to get set to 0 instantly? so it's done like this.
|
||||||
|
p->rdaddmomx = (p->rdaddmomx*9)/10;
|
||||||
|
p->rdaddmomy = (p->rdaddmomy*9)/10;
|
||||||
|
p->rideroidrollangle /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and now, going up/down
|
||||||
|
|
||||||
|
if (p->cmd.throwdir > 0)
|
||||||
|
{
|
||||||
|
// if we were going the opposite direction, this helps us change our height very easily.
|
||||||
|
if (p->rdaddmomz < 0)
|
||||||
|
p->rdaddmomz /= 2;
|
||||||
|
|
||||||
|
p->rdaddmomz = min(RIDEROIDMAXADD*mapobjectscale/7, p->rdaddmomz + mapobjectscale/16);
|
||||||
|
|
||||||
|
if (p->rideroidspeed > RIDEROIDSPEED/2
|
||||||
|
&& abs(p->cmd.turning) > 400
|
||||||
|
&& leveltime & 1)
|
||||||
|
p->rideroidspeed -= 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (p->cmd.throwdir < 0)
|
||||||
|
{
|
||||||
|
// if we were going the opposite direction, this helps us change our height very easily.
|
||||||
|
if (p->rdaddmomz > 0)
|
||||||
|
p->rdaddmomz /= 2;
|
||||||
|
|
||||||
|
p->rdaddmomz = max(-RIDEROIDMAXADD*mapobjectscale/7, p->rdaddmomz - mapobjectscale/16);
|
||||||
|
|
||||||
|
if (p->rideroidspeed > RIDEROIDSPEED/2
|
||||||
|
&& abs(p->cmd.turning) > 400
|
||||||
|
&& leveltime & 1)
|
||||||
|
p->rideroidspeed -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p->rdaddmomz = (p->rdaddmomz*6)/10;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// transposed lua code.
|
||||||
|
// the lua used to continuously P_SpawnMobj the letters which was fine for the intended use case in the original LV iteration.
|
||||||
|
// however the LV remake spams a lot of these rideroid nodes close to each other which created a huge overhead whether or not they were being displayed.
|
||||||
|
// so now it's more optimized and only spawns things once.
|
||||||
|
|
||||||
|
void Obj_RideroidNodeSpawn(mobj_t *mo)
|
||||||
|
{
|
||||||
|
|
||||||
|
fixed_t radius = NODERADIUS*mapobjectscale; // radius for the text to rotate at.
|
||||||
|
mobj_t *ptr = mo;
|
||||||
|
UINT8 i;
|
||||||
|
UINT8 j;
|
||||||
|
|
||||||
|
|
||||||
|
// make it bigger.
|
||||||
|
P_SetScale(mo, mo->scale*3);
|
||||||
|
|
||||||
|
// spawn the letter things.
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
angle_t ang = mo->angle + (i)*180*ANG1;
|
||||||
|
fixed_t zpos = mo->z + 64*mapobjectscale + mapobjectscale*96*i;
|
||||||
|
|
||||||
|
for (j = 0; j < 7; j++)
|
||||||
|
{
|
||||||
|
fixed_t xpos = mo->x + FixedMul(radius, FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
fixed_t ypos = mo->y + FixedMul(radius, FINESINE(ang>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
mobj_t *let = P_SpawnMobj(xpos, ypos, zpos, MT_THOK);
|
||||||
|
let->sprite = SPR_RDRL;
|
||||||
|
let->frame = j|FF_FULLBRIGHT|FF_PAPERSPRITE;
|
||||||
|
let->fuse = -1;
|
||||||
|
let->tics = -1;
|
||||||
|
let->angle = ang + ANG1*90;
|
||||||
|
let->scale = 2*mapobjectscale;
|
||||||
|
|
||||||
|
// set letter in previous thing's hnext, this will let us loop em easily in the looping thinker.
|
||||||
|
P_SetTarget(&ptr->hnext, let);
|
||||||
|
|
||||||
|
// set the ptr to the last letter spawned.
|
||||||
|
ptr = let;
|
||||||
|
|
||||||
|
ang += ANG1*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Obj_RideroidNodeThink(mobj_t *mo)
|
||||||
|
{
|
||||||
|
fixed_t radius = NODERADIUS*mapobjectscale; // radius for the text to rotate at.
|
||||||
|
mobj_t *ptr = mo->hnext;
|
||||||
|
mobj_t *pmo;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
mo->angle -= NODEROTSPEED; // continuously rotate.
|
||||||
|
|
||||||
|
while (ptr && !P_MobjWasRemoved(ptr))
|
||||||
|
{
|
||||||
|
// get the new position, move us here, and move on to the next object in line.
|
||||||
|
angle_t newang = ptr->angle - NODEROTSPEED;
|
||||||
|
fixed_t newxpos = mo->x + FixedMul(radius, FINECOSINE((newang - ANG1*90)>>ANGLETOFINESHIFT));
|
||||||
|
fixed_t newypos = mo->y + FixedMul(radius, FINESINE((newang - ANG1*90)>>ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
P_MoveOrigin(ptr, newxpos, newypos, ptr->z);
|
||||||
|
ptr->angle = newang;
|
||||||
|
|
||||||
|
ptr = ptr->hnext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for players coming near us.
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator || players[i].rideroid || players[i].rdnodepull)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pmo = players[i].mo;
|
||||||
|
//CONS_Printf("rd: %d\n", players[i].rideroid);
|
||||||
|
|
||||||
|
if (R_PointToDist2(mo->x, mo->y, pmo->x, pmo->y) < NODERADIUS*mapobjectscale
|
||||||
|
&& pmo->z + pmo->height >= mo->z
|
||||||
|
&& pmo->z <= mo->z + 512*mapobjectscale)
|
||||||
|
{
|
||||||
|
|
||||||
|
mobj_t *rd;
|
||||||
|
|
||||||
|
plr_undoRespawn(&players[i]);
|
||||||
|
plr_resetRideroidVars(&players[i]);
|
||||||
|
|
||||||
|
players[i].rdnodepull = true;
|
||||||
|
players[i].rideroidangle = mo->spawnpoint->angle*ANG1; // reminder that mo->angle changes, so we use the spawnpoint angle.
|
||||||
|
players[i].rideroidspeed = RIDEROIDSPEED/8;
|
||||||
|
|
||||||
|
P_SetTarget(&pmo->tracer, mo);
|
||||||
|
|
||||||
|
// spawn the rideroid.
|
||||||
|
rd = P_SpawnMobj(mo->x, mo->y, mo->z, MT_RIDEROID);
|
||||||
|
rd->angle = players[i].rideroidangle;
|
||||||
|
P_SetTarget(&rd->target, pmo);
|
||||||
|
|
||||||
|
//S_StartSound(rd, sfx_ridr1);
|
||||||
|
|
||||||
|
//CONS_Printf("rd pull\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/p_mobj.c
17
src/p_mobj.c
|
|
@ -9633,6 +9633,20 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
case MT_RAINBOWDASHRING:
|
case MT_RAINBOWDASHRING:
|
||||||
Obj_RainbowDashRingThink(mobj);
|
Obj_RainbowDashRingThink(mobj);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MT_RIDEROID:
|
||||||
|
Obj_RideroidThink(mobj);
|
||||||
|
if (P_MobjWasRemoved(mobj))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MT_RIDEROIDNODE:
|
||||||
|
Obj_RideroidNodeThink(mobj);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// check mobj against possible water content, before movement code
|
// check mobj against possible water content, before movement code
|
||||||
P_MobjCheckWater(mobj);
|
P_MobjCheckWater(mobj);
|
||||||
|
|
@ -11043,6 +11057,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||||
case MT_RAINBOWDASHRING:
|
case MT_RAINBOWDASHRING:
|
||||||
Obj_RainbowDashRingSpawn(mobj);
|
Obj_RainbowDashRingSpawn(mobj);
|
||||||
break;
|
break;
|
||||||
|
case MT_RIDEROIDNODE:
|
||||||
|
Obj_RideroidNodeSpawn(mobj);
|
||||||
|
break;
|
||||||
case MT_SNEAKERPANEL:
|
case MT_SNEAKERPANEL:
|
||||||
Obj_SneakerPanelSpawn(mobj);
|
Obj_SneakerPanelSpawn(mobj);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue