mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +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_SPARK10",
|
||||
"S_CHECKPOINT_SPARK11",
|
||||
|
||||
"S_RIDEROID",
|
||||
"S_RIDEROID_ICON",
|
||||
};
|
||||
|
||||
// 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_SCRIPT_THING",
|
||||
|
||||
"MT_RIDEROID",
|
||||
"MT_RIDEROIDNODE",
|
||||
};
|
||||
|
||||
const char *const MOBJFLAG_LIST[] = {
|
||||
|
|
|
|||
|
|
@ -30439,7 +30439,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
0, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
MF_NOGRAVITY, // flags
|
||||
MF_NOGRAVITY|MF_NOCLIP, // flags
|
||||
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);
|
||||
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
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
sneaker-panel.c
|
||||
emerald.c
|
||||
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:
|
||||
Obj_RainbowDashRingThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_RIDEROID:
|
||||
Obj_RideroidThink(mobj);
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MT_RIDEROIDNODE:
|
||||
Obj_RideroidNodeThink(mobj);
|
||||
break;
|
||||
|
||||
default:
|
||||
// check mobj against possible water content, before movement code
|
||||
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:
|
||||
Obj_RainbowDashRingSpawn(mobj);
|
||||
break;
|
||||
case MT_RIDEROIDNODE:
|
||||
Obj_RideroidNodeSpawn(mobj);
|
||||
break;
|
||||
case MT_SNEAKERPANEL:
|
||||
Obj_SneakerPanelSpawn(mobj);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue