mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Hardcode the remainder of the WPZ objects
This commit is contained in:
parent
df31c65ebb
commit
a710237fde
5 changed files with 502 additions and 0 deletions
|
|
@ -273,6 +273,13 @@ void Obj_WPZTurbineThinker(mobj_t *mo);
|
|||
void Obj_playerWPZTurbine(player_t *p);
|
||||
void Obj_WPZBubbleThink(mobj_t *mo);
|
||||
|
||||
/* WPZ Fountains */
|
||||
void Obj_WPZFountainThink(mobj_t *mo);
|
||||
|
||||
/* WPZ Kuragens */
|
||||
void Obj_WPZKuragenThink(mobj_t *mo);
|
||||
void Obj_WPZKuragenBombThink(mobj_t *mo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,5 +36,6 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
dlzseasaw.c
|
||||
dlzothers.c
|
||||
wpzturbine.c
|
||||
wpzothers.c
|
||||
shadow.cpp
|
||||
)
|
||||
|
|
|
|||
97
src/objects/wpzothers.c
Normal file
97
src/objects/wpzothers.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
// 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 wpzturbine.c
|
||||
/// \brief Water Palace Zone turbines and associated bubble object. Yep, this is going to suck.
|
||||
|
||||
#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"
|
||||
|
||||
// foutains
|
||||
void Obj_WPZFountainThink(mobj_t *mo)
|
||||
{
|
||||
if (mo->state == &states[S_WPZFOUNTAIN]
|
||||
&& !(mo->eflags & MFE_UNDERWATER))
|
||||
P_SetMobjState(mo, S_WPZFOUNTAINANIM);
|
||||
|
||||
else if (mo->state == &states[S_WPZFOUNTAINANIM]
|
||||
&& mo->eflags & MFE_UNDERWATER)
|
||||
P_SetMobjState(mo, S_WPZFOUNTAIN);
|
||||
}
|
||||
|
||||
// kuragens
|
||||
void Obj_WPZKuragenThink(mobj_t *mo)
|
||||
{
|
||||
boolean active = false;
|
||||
|
||||
P_SetScale(mo, mapobjectscale*2);
|
||||
|
||||
if (!(mo->spawnpoint->options & 1 || mo->spawnpoint->thing_args[0])) // extra flag skips player checks, making it a decoration.
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *p;
|
||||
mobj_t *pmo;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
pmo = p->mo;
|
||||
|
||||
if (R_PointToDist2(pmo->x, pmo->y, mo->x, mo->y) < mapobjectscale*6144)
|
||||
{
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active && mo->extravalue1)
|
||||
{
|
||||
mo->extravalue1--;
|
||||
|
||||
if (!mo->extravalue1)
|
||||
{
|
||||
mobj_t *b = P_SpawnMobj(mo->x, mo->y, mo->z, MT_KURAGENBOMB);
|
||||
b->flags2 = mo->flags2 & MF2_OBJECTFLIP;
|
||||
P_SetScale(b, mapobjectscale*2);
|
||||
b->destscale = mapobjectscale*2;
|
||||
mo->extravalue1 = TICRATE*5;
|
||||
}
|
||||
}
|
||||
else
|
||||
mo->extravalue1 = TICRATE*5/2;
|
||||
}
|
||||
|
||||
// kuragen bomb
|
||||
void Obj_WPZKuragenBombThink(mobj_t *mo)
|
||||
{
|
||||
if (P_IsObjectOnGround(mo))
|
||||
{
|
||||
P_SetScale(mo, mapobjectscale/2);
|
||||
P_RadiusAttack(mo, mo, FRACUNIT*192, DMG_EXPLODE, false);
|
||||
A_MineExplode(mo);
|
||||
|
||||
P_RemoveMobj(mo);
|
||||
}
|
||||
}
|
||||
385
src/objects/wpzturbine.c
Normal file
385
src/objects/wpzturbine.c
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
// 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 wpzturbine.c
|
||||
/// \brief Water Palace Zone turbines and associated bubble object. Yep, this is going to suck.
|
||||
|
||||
#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"
|
||||
|
||||
// distance to spawn the fan from the center:
|
||||
#define TURBINE_RADIUS 128
|
||||
|
||||
// default distance at which players activate the turbine:
|
||||
#define TURBINE_RANGE (2048*FRACUNIT)
|
||||
|
||||
// default distance at which players spin away from the turbine
|
||||
#define TURBINE_SPIN 1536
|
||||
|
||||
// spawns the hnext visual list for the turbine.
|
||||
// whether we use it or not will depend on its flags.
|
||||
void Obj_WPZTurbineSpawn(mobj_t *mo)
|
||||
{
|
||||
mobj_t *ptr = mo;
|
||||
UINT8 i;
|
||||
|
||||
// spawn the visuals regardless of flags, make em invisible.
|
||||
// we'll care about updating em if it's worth doing later.
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
|
||||
P_SetMobjState(vis, S_INVISIBLE);
|
||||
vis->tics = 4; // if we don't use it just despawn it later.
|
||||
|
||||
P_SetTarget(&ptr->hnext, vis);
|
||||
ptr = vis;
|
||||
}
|
||||
}
|
||||
|
||||
// visually update the turbine's hnext visuals if need be.
|
||||
static void Obj_WPZTurbineUpdate(mobj_t *mo)
|
||||
{
|
||||
angle_t ang = (angle_t)mo->extravalue1;
|
||||
mapthing_t *mt = mo->spawnpoint;
|
||||
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
// fans
|
||||
if (!mt->thing_args[1])
|
||||
{
|
||||
UINT8 i;
|
||||
mobj_t *ptr = mo;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
fixed_t x = mo->x + FixedMul(mapobjectscale, TURBINE_RADIUS*FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
fixed_t y = mo->y + FixedMul(mapobjectscale, TURBINE_RADIUS*FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
// get the mobj
|
||||
if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext))
|
||||
{
|
||||
ptr = ptr->hnext;
|
||||
P_MoveOrigin(ptr, x, y, mo->z);
|
||||
ptr->tics = 4;
|
||||
ptr->sprite = SPR_WPWL;
|
||||
ptr->frame = 1|FF_PAPERSPRITE;
|
||||
P_SetScale(ptr, mapobjectscale*4);
|
||||
ptr->destscale = mapobjectscale*4;
|
||||
ptr->angle = ang;
|
||||
}
|
||||
|
||||
ang += (360/8)*ANG1;
|
||||
}
|
||||
}
|
||||
|
||||
// bubbles if we're underwater
|
||||
if (mo->eflags & MFE_UNDERWATER && leveltime%(TICRATE/2) == 0)
|
||||
{
|
||||
|
||||
INT32 dradius = TURBINE_SPIN;
|
||||
INT32 bubbleradius;
|
||||
angle_t bubbleang;
|
||||
fixed_t bx, by, bz;
|
||||
mobj_t *bubble;
|
||||
|
||||
if (mt->thing_args[7])
|
||||
dradius = mt->thing_args[7];
|
||||
|
||||
bubbleradius = P_RandomRange(PR_FUZZ, dradius/4, dradius);
|
||||
bubbleang = P_RandomRange(PR_FUZZ, 0, 359)*ANG1;
|
||||
|
||||
bx = mo->x + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT));
|
||||
by = mo->y + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT));
|
||||
bz = R_PointInSubsector(bx, by)->sector->floorheight;
|
||||
|
||||
bubble = P_SpawnMobj(bx, by, bz, MT_WATERPALACEBUBBLE);
|
||||
bubble->fuse = TICRATE*10;
|
||||
bubble->angle = bubbleang;
|
||||
bubble->movecount = bubbleradius;
|
||||
P_SetTarget(&bubble->tracer, mo);
|
||||
}
|
||||
}
|
||||
|
||||
void Obj_WPZTurbineThinker(mobj_t *mo)
|
||||
{
|
||||
|
||||
UINT8 i;
|
||||
mapthing_t *mt = mo->spawnpoint;
|
||||
boolean opt1 = mt->thing_args[0] != 0;
|
||||
fixed_t baseheight = (mt->thing_args[2]) ? (mt->thing_args[2]*FRACUNIT) : (mo->z+mapobjectscale*1024);
|
||||
fixed_t sneakerheight = (mt->thing_args[3]) ? (mt->thing_args[3]*FRACUNIT) : (mo->z+mapobjectscale*1768);
|
||||
fixed_t range = (mt->thing_args[7]) ? (mt->thing_args[7]*FRACUNIT) : (FixedMul(mapobjectscale, TURBINE_RANGE));
|
||||
INT32 rotspeed = (mt->thing_args[5]) ? (mt->thing_args[5]*ANG1/10) : (ANG1*3); // not angle_t for negatives.
|
||||
tic_t turbinetime = (mt->thing_args[4]) ? (mt->thing_args[4]) : (TICRATE*3);
|
||||
SINT8 mult = (opt1) ? (-1) : (1);
|
||||
|
||||
mo->extravalue1 += rotspeed*mult;
|
||||
|
||||
// find players in range and take their phones.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *p;
|
||||
mobj_t *pmo;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator || K_isPlayerInSpecialState(&players[i]))
|
||||
continue;
|
||||
|
||||
p = &players[i];
|
||||
pmo = p->mo;
|
||||
|
||||
if (R_PointToDist2(pmo->x, pmo->y, mo->x, mo->y) < range
|
||||
&& !p->turbine
|
||||
&& !p->respawn.timer)
|
||||
{
|
||||
P_SetTarget(&pmo->tracer, mo);
|
||||
p->turbine = turbinetime;
|
||||
|
||||
// to be fully honest i dont rememebr what i was on while writing this
|
||||
// but it originally went by mo instead of pmo for angle??? how did it ever *work* ?
|
||||
p->turbineangle = ANGLE_180 + R_PointToAngle2(0, 0, mo->momx, mo->momy);
|
||||
if (!p->speed)
|
||||
p->turbineangle = ANGLE_180 + mo->angle;
|
||||
|
||||
p->turbineangle += ANG1*45*mult;
|
||||
|
||||
p->turbineheight = baseheight;
|
||||
p->turbinespd = false;
|
||||
|
||||
if (FixedDiv(p->speed, K_GetKartSpeed(p, false, false)) > FRACUNIT + FRACUNIT/3 // 133% speed
|
||||
&& baseheight != sneakerheight)
|
||||
{
|
||||
p->turbineheight = sneakerheight;
|
||||
p->turbinespd = true;
|
||||
}
|
||||
|
||||
pmo->flags |= MF_NOCLIP;
|
||||
}
|
||||
}
|
||||
Obj_WPZTurbineUpdate(mo);
|
||||
}
|
||||
|
||||
// ported from my lua for convenience of not having to rewrite half the shit code.
|
||||
static INT32 angtoint(angle_t a)
|
||||
{
|
||||
return a/ANG1;
|
||||
}
|
||||
|
||||
// controls player while using a turbine.
|
||||
// i do not remember what i smoked before writing the lua version of this code.
|
||||
// it's a fucking mess what the fuck does half of this even DO
|
||||
void Obj_playerWPZTurbine(player_t *p)
|
||||
{
|
||||
mobj_t *pmo = p->mo;
|
||||
mobj_t *t = pmo->tracer;
|
||||
mapthing_t *mt;
|
||||
boolean opt1;
|
||||
fixed_t dist = FixedMul(mapobjectscale, TURBINE_SPIN)*FRACUNIT;
|
||||
INT32 speed = ANG1*3;
|
||||
boolean mode = false;
|
||||
boolean distreached;
|
||||
|
||||
fixed_t tx, ty, tz;
|
||||
fixed_t momz;
|
||||
|
||||
|
||||
if (!t || P_MobjWasRemoved(t))
|
||||
{
|
||||
p->turbine = false;
|
||||
P_SetTarget(&pmo->tracer, NULL);
|
||||
return; // wtf happened
|
||||
}
|
||||
|
||||
mt = t->spawnpoint;
|
||||
|
||||
opt1 = (mt->thing_args[0] != 0);
|
||||
|
||||
if (mt->thing_args[6])
|
||||
dist = mt->thing_args[6]*FRACUNIT;
|
||||
|
||||
if (mt->thing_args[5])
|
||||
speed = mt->thing_args[5]*ANG1/10;
|
||||
|
||||
if (mt->thing_args[9])
|
||||
mode = true;
|
||||
|
||||
distreached = R_PointToDist2(t->x, t->y, pmo->x, pmo->y) <= dist+32*mapobjectscale;
|
||||
|
||||
if (mode && !distreached)
|
||||
p->turbineangle = (INT32)R_PointToAngle2(t->x, t->y, pmo->x, pmo->y);
|
||||
|
||||
p->spinouttimer = TICRATE;
|
||||
pmo->pitch = 0;
|
||||
|
||||
// determine target x/y/z
|
||||
tx = t->x + (dist/FRACUNIT)*FINECOSINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT);
|
||||
ty = t->y + (dist/FRACUNIT)*FINESINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT);
|
||||
tz = p->turbineheight;
|
||||
|
||||
//CONS_Printf("%d %d\n", tx/FRACUNIT, ty/FRACUNIT);
|
||||
|
||||
if (mode)
|
||||
{
|
||||
if (distreached)
|
||||
{
|
||||
P_MoveOrigin(pmo, tx, ty, pmo->z);
|
||||
}
|
||||
else
|
||||
{
|
||||
pmo->momx = FixedMul(FINECOSINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT), -(max(p->speed, mapobjectscale*32)));
|
||||
pmo->momy = FixedMul(FINESINE((angle_t)(p->turbineangle)>>ANGLETOFINESHIFT), -(max(p->speed, mapobjectscale*32)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pmo->momx = (tx - pmo->x)/24 * (p->turbinespd ? 2 : 1);
|
||||
pmo->momy = (ty - pmo->y)/24 * (p->turbinespd ? 2 : 1);
|
||||
}
|
||||
|
||||
momz = (tz - pmo->z)/128 * (p->turbinespd+1);
|
||||
|
||||
if (mt->thing_args[8])
|
||||
{
|
||||
momz = (mt->thing_args[8]*FRACUNIT) * ((tz < pmo->z) ? -1 : 1);
|
||||
|
||||
if (momz < 0)
|
||||
{
|
||||
if (pmo->z + momz < tz)
|
||||
{
|
||||
momz = pmo->z - tz;
|
||||
}
|
||||
}
|
||||
else if (momz > 0)
|
||||
{
|
||||
if (pmo->z + momz > tz)
|
||||
{
|
||||
momz = tz - pmo->z;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pmo->momz = momz;
|
||||
p->turbineangle += (speed * (p->turbinespd ? 2 : 1)) * (opt1 ? -1 : 1);
|
||||
P_SetPlayerAngle(p, (angle_t)p->turbineangle + ANGLE_90*(opt1 ? -1 : 1));
|
||||
|
||||
if (pmo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
fixed_t rx = pmo->x + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
fixed_t ry = pmo->y + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
fixed_t rz = pmo->z + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
|
||||
mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK);
|
||||
P_SetScale(bubl, pmo->scale*2);
|
||||
bubl->scalespeed = pmo->scale/12;
|
||||
bubl->destscale = 1;
|
||||
bubl->sprite = SPR_BUBL;
|
||||
bubl->frame = 0;
|
||||
bubl->tics = TICRATE;
|
||||
}
|
||||
|
||||
|
||||
if (pmo->momz < mapobjectscale*6)
|
||||
{
|
||||
INT32 myang = angtoint(pmo->angle);
|
||||
angle_t exitangle = t->angle;
|
||||
INT32 targetangle = angtoint(exitangle);
|
||||
INT32 launchangle = myang-targetangle;
|
||||
|
||||
// WHAT WAS I SMOKING
|
||||
if ( (opt1 && launchangle > -60 && launchangle < -45)
|
||||
|| (!opt1 && launchangle > 45 && launchangle < 60))
|
||||
{
|
||||
|
||||
P_SetPlayerAngle(p, targetangle*ANG1);
|
||||
|
||||
if (mode)
|
||||
P_InstaThrust(pmo, targetangle*ANG1, 128*mapobjectscale);
|
||||
else
|
||||
{
|
||||
fixed_t spd = FixedHypot(pmo->momx, pmo->momy);
|
||||
P_InstaThrust(pmo, targetangle*ANG1, spd);
|
||||
}
|
||||
|
||||
P_SetTarget(&pmo->tracer, NULL);
|
||||
p->turbineheight = 0;
|
||||
p->turbineangle = 0;
|
||||
|
||||
if (p->turbinespd)
|
||||
pmo->momz = mapobjectscale*5 * (pmo->eflags & MFE_UNDERWATER ? 2 : 1);
|
||||
|
||||
if (pmo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
pmo->momz = mapobjectscale*5;
|
||||
pmo->momx = (pmo->momx*17)/10;
|
||||
pmo->momy = (pmo->momy*17)/10;
|
||||
}
|
||||
|
||||
p->spinouttimer = 0;
|
||||
pmo->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bubbles that circle the turbine
|
||||
void Obj_WPZBubbleThink(mobj_t *mo)
|
||||
{
|
||||
angle_t ang = mo->angle - ANGLE_90;
|
||||
mobj_t *t = mo->tracer;
|
||||
fixed_t tx, ty;
|
||||
mapthing_t *mt;
|
||||
|
||||
// where
|
||||
// where did it go
|
||||
if (!t || P_MobjWasRemoved(t))
|
||||
{
|
||||
P_RemoveMobj(mo);
|
||||
return;
|
||||
}
|
||||
|
||||
mt = mo->spawnpoint;
|
||||
if (!mt)
|
||||
return;
|
||||
|
||||
mo->momz = mapobjectscale*16;
|
||||
tx = mo->tracer->x + FixedMul(mapobjectscale, mo->movefactor*FINECOSINE(ang>>ANGLETOFINESHIFT));
|
||||
ty = mo->tracer->y + FixedMul(mapobjectscale, mo->movefactor*FINESINE(ang>>ANGLETOFINESHIFT));
|
||||
|
||||
mo->momx = (tx - mo->x)/24;
|
||||
mo->momy = (ty - mo->y)/24;
|
||||
|
||||
if (leveltime & 1)
|
||||
{
|
||||
fixed_t rx = mo->x + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
fixed_t ry = mo->y + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
fixed_t rz = mo->z + P_RandomRange(PR_FUZZ, -64, 64)*mapobjectscale;
|
||||
mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK);
|
||||
P_SetScale(bubl, mapobjectscale*4);
|
||||
bubl->destscale = 1;
|
||||
bubl->sprite = SPR_BUBL;
|
||||
bubl->frame = 0;
|
||||
bubl->tics = TICRATE;
|
||||
}
|
||||
|
||||
mo->angle += 3*ANG1 * (mt->thing_args[0] ? -1 : 1);
|
||||
}
|
||||
12
src/p_mobj.c
12
src/p_mobj.c
|
|
@ -9745,6 +9745,18 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
Obj_WPZBubbleThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_WATERPALACEFOUNTAIN:
|
||||
Obj_WPZFountainThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_KURAGEN:
|
||||
Obj_WPZKuragenThink(mobj);
|
||||
break;
|
||||
|
||||
case MT_KURAGENBOMB:
|
||||
Obj_WPZKuragenBombThink(mobj);
|
||||
break;
|
||||
|
||||
default:
|
||||
// check mobj against possible water content, before movement code
|
||||
P_MobjCheckWater(mobj);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue