From 2a8a6d6ccc63264c6d1c171399fae6e371193c34 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 18 Sep 2023 01:24:19 +0200 Subject: [PATCH 01/39] rideroid: player vars --- src/d_player.h | 14 +++++++++++++- src/p_saveg.c | 20 +++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 1bc0d07e6..85be7c772 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -717,7 +717,19 @@ struct player_t tic_t spheredigestion; SINT8 glanceDir; // Direction the player is trying to look backwards in - + + ////////////// + // rideroid // + ////////////// + boolean rideroid; // on rideroid y/n + boolean rdnodepull; // being pulled by rideroid node. mo target is set to the node while this is true. + angle_t rideroidangle; // angle the rideroid is going at. This doesn't change once we're on it. + fixed_t rideroidspeed; // speed the rideroid is to be moving at. + fixed_t rideroidrollangle; // rollangle while turning + fixed_t rdaddmomx; // some speed variables to smoothe things out without fighting with the regular momentum system. + fixed_t rdaddmomy; + fixed_t rdaddmomz; + // SINT8 lives; diff --git a/src/p_saveg.c b/src/p_saveg.c index 7f2410694..4af1c0b33 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -553,7 +553,16 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].ringboxdelay); WRITEUINT8(save->p, players[i].ringboxaward); WRITEFIXED(save->p, players[i].outrun); - + + WRITEUINT8(save->p, players[i].rideroid); + WRITEUINT8(save->p, players[i].rdnodepull); + WRITEANGLE(save->p, players[i].rideroidangle); + WRITEFIXED(save->p, players[i].rideroidspeed); + WRITEANGLE(save->p, players[i].rideroidrollangle); + WRITEFIXED(save->p, players[i].rdaddmomx); + WRITEFIXED(save->p, players[i].rdaddmomy); + WRITEFIXED(save->p, players[i].rdaddmomz); + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -1028,6 +1037,15 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].ringboxdelay = READUINT8(save->p); players[i].ringboxaward = READUINT8(save->p); players[i].outrun = READFIXED(save->p); + + players[i].rideroid = READUINT8(save->p); + players[i].rdnodepull = READUINT8(save->p); + players[i].rideroidangle = READANGLE(save->p); + players[i].rideroidspeed = READFIXED(save->p); + players[i].rideroidrollangle = READANGLE(save->p); + players[i].rdaddmomx = READFIXED(save->p); + players[i].rdaddmomy = READFIXED(save->p); + players[i].rdaddmomz = READFIXED(save->p); // respawnvars_t players[i].respawn.state = READUINT8(save->p); From 56d8ae67ae5665e3ecc02009ffa8caf46319cbc1 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 18 Sep 2023 08:55:22 +0200 Subject: [PATCH 02/39] Base mobj/state/sound definitions --- src/info.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/info.h | 18 +++++++++++--- src/sounds.h | 6 +++++ 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 2343b81e3..cd5337c81 100644 --- a/src/info.c +++ b/src/info.c @@ -891,7 +891,13 @@ char sprnames[NUMSPRITES + 1][5] = "CPT1", // Checkpoint Orb "CPT2", // Checkpoint Stick "CPT3", // Checkpoint Base - + + // rideroid (see info.h for detail) + "RDRD", + "RDRA", + "RDRC", + "RDRL", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5414,6 +5420,10 @@ state_t states[NUMSTATES] = {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK10}, // S_CHECKPOINT_SPARK9 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK11}, // S_CHECKPOINT_SPARK10 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK1}, // S_CHECKPOINT_SPARK11 + + {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID + {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON + }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -30378,6 +30388,61 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, + + { // MT_RIDEROID + -1, // doomednum + S_RIDEROID, // 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 + 0, // speed + 80*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + + { // MT_RIDEROIDNODE + 3711, // doomednum + S_RIDEROID_ICON, // 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 + 0, // speed + 80*FRACUNIT, // radius + 80*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index ef47c05bc..d364efc36 100644 --- a/src/info.h +++ b/src/info.h @@ -1445,7 +1445,12 @@ typedef enum sprite SPR_CPT1, // Checkpoint Orb SPR_CPT2, // Checkpoint Stick SPR_CPT3, // Checkpoint Base - + + SPR_RDRD, // rideroid + SPR_RDRA, // rideroid node sprites + SPR_RDRC, + SPR_RDRL, + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -5842,7 +5847,11 @@ typedef enum state S_CHECKPOINT_SPARK9, S_CHECKPOINT_SPARK10, S_CHECKPOINT_SPARK11, - + + // rideroid + S_RIDEROID, + S_RIDEROID_ICON, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -7013,7 +7022,10 @@ typedef enum mobj_type MT_CHECKPOINT_END, MT_SCRIPT_THING, - + + MT_RIDEROID, + MT_RIDEROIDNODE, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/sounds.h b/src/sounds.h index b9b0616e0..796c6f8d4 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1278,6 +1278,12 @@ typedef enum sfx_rainbr, sfx_rank, + + // rideroid + sfx_ridr1, + sfx_ridr2, + sfx_ridr3, + sfx_ridr4, // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight From aef958d7ed1c4289ec43e8a731218a40dcad6f03 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 18 Sep 2023 16:54:16 +0200 Subject: [PATCH 03/39] Rideroid: first pass --- src/deh_tables.c | 6 + src/info.c | 2 +- src/k_objects.h | 7 + src/objects/CMakeLists.txt | 1 + src/objects/rideroid.c | 498 +++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 17 ++ 6 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 src/objects/rideroid.c diff --git a/src/deh_tables.c b/src/deh_tables.c index f4112f614..0749e1665 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -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[] = { diff --git a/src/info.c b/src/info.c index cd5337c81..291169514 100644 --- a/src/info.c +++ b/src/info.c @@ -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 }, diff --git a/src/k_objects.h b/src/k_objects.h index 7050ddff4..83c704b1f 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -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 diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index c3b01f4a0..366a0a0f7 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -29,4 +29,5 @@ target_sources(SRB2SDL2 PRIVATE sneaker-panel.c emerald.c checkpoint.cpp + rideroid.c ) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c new file mode 100644 index 000000000..405630f83 --- /dev/null +++ b/src/objects/rideroid.c @@ -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"); + + } + } +} diff --git a/src/p_mobj.c b/src/p_mobj.c index 4f1b97657..a17e1eef7 100644 --- a/src/p_mobj.c +++ b/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; From 908bbba4ec418eea764fd36964cd20fcbe146ec3 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 18 Sep 2023 18:14:00 +0200 Subject: [PATCH 04/39] Rideroid: second pass --- src/info.c | 4 +- src/k_objects.h | 2 +- src/objects/rideroid.c | 94 +++++++++++++++++++++++++++++++----------- src/p_map.c | 9 +++- src/sounds.c | 5 +++ 5 files changed, 86 insertions(+), 28 deletions(-) diff --git a/src/info.c b/src/info.c index 291169514..a8c684a0e 100644 --- a/src/info.c +++ b/src/info.c @@ -30406,13 +30406,13 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 80*FRACUNIT, // radius + 30*FRACUNIT, // radius 40*FRACUNIT, // height 0, // display offset 0, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, diff --git a/src/k_objects.h b/src/k_objects.h index 83c704b1f..432063383 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -227,9 +227,9 @@ 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); +void Obj_getPlayerOffRideroid(mobj_t *mo); // used in p_map.c to get off of em when passing transfer lines. #ifdef __cplusplus diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 405630f83..bd3600693 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -56,21 +56,42 @@ static void plr_resetRideroidVars(player_t *p) // kills the rideroid and removes it from the map. static void Obj_killRideroid(mobj_t *mo) { + UINT8 i; + + for (i = 0; i < 32; i++) + { + mobj_t *t = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + t->color = SKINCOLOR_TEAL; + t->frame = FF_FULLBRIGHT; + t->destscale = 1; + t->momx = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; + t->momy = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; + t->momz = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; + } 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) +// makes the player get off of the rideroid. +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)) + if (pmo && !P_MobjWasRemoved(pmo)) + { + player_t *p = pmo->player; + + pmo->flags &= ~MF_NOGRAVITY; + plr_resetRideroidVars(p); + mo->fuse = TICRATE/2; + mo->momx = mo->momx*2; + mo->momy = mo->momy*2; + mo->momz = 0; + mo->target = NULL; + + S_StartSound(mo, sfx_ridr4); + + } } // this assumes mo->target and mo->target->player is valid. @@ -97,19 +118,23 @@ static fixed_t Obj_rideroidLerp(INT32 start, INT32 finish, INT32 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 + player_t *p; UINT8 i, j; angle_t h_an = mo->angle + ANG1*90; + + if (pmo && !P_MobjWasRemoved(pmo)) + { + p = pmo->player; // used to make some graphics local to save on framerate + mo->color = pmo->color; + mo->colorized = pmo->colorized; + } // 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++) { @@ -135,7 +160,7 @@ static void Obj_rideroidTrail(mobj_t *mo) P_SetScale(t, max(1, mapobjectscale*5/6 - ((10-j)*mapobjectscale/120))); t->destscale = 1; - if (p != &players[consoleplayer] && j) + if (p && p != &players[consoleplayer] && j) t->renderflags |= RF_DONTDRAW; } @@ -156,6 +181,10 @@ static void Obj_updateRideroidPos(mobj_t *mo) fixed_t y = pmo->y + 2*FINESINE(pmo->angle>>ANGLETOFINESHIFT); P_MoveOrigin(mo, x, y, pmo->z - 10*mapobjectscale); + mo->momx = pmo->momx; + mo->momy = pmo->momy; + mo->momz = pmo->momz; + Obj_rideroidTrail(mo); } @@ -176,7 +205,19 @@ void Obj_RideroidThink(mobj_t *mo) if (!pmo || P_MobjWasRemoved(pmo)) { - Obj_killRideroid(mo); + if (!mo->fuse) + { + mo->fuse = TICRATE/2; + } + else if (mo->fuse == 1) + { + Obj_killRideroid(mo); + } + else + { + Obj_rideroidTrail(mo); + mo->rollangle += ANG1*24; + } return; } @@ -197,7 +238,7 @@ void Obj_RideroidThink(mobj_t *mo) p->rideroid = true; p->rdnodepull = false; - //S_StartSound(pmo, sfx_ridr2); + S_StartSound(pmo, sfx_ridr2); } return; @@ -231,8 +272,8 @@ void Obj_RideroidThink(mobj_t *mo) mo->movecount++; // we use this as a timer for sounds and whatnot. - //if (mo->movecount == 1 || !(mo->movecount%TICRATE)) - //S_StartSound(mo, sfx_ridr3); + if (mo->movecount == 1 || !(mo->movecount%TICRATE)) + S_StartSound(mo, sfx_ridr3); // aaaaand the actual gameplay and shit... wooooo @@ -294,7 +335,7 @@ void Obj_RideroidThink(mobj_t *mo) if (p->cmd.turning < -400) { - P_Thrust(pmo, mo->angle - 90*ANG1, 2*mapobjectscale); + P_Thrust(pmo, mo->angle - ANGLE_90, 2*mapobjectscale); p->rideroidrollangle -= ANG1*3; if (p->rideroidrollangle < -ANG1*25) @@ -305,7 +346,7 @@ void Obj_RideroidThink(mobj_t *mo) } else if (p->cmd.turning > 400) { - P_Thrust(pmo, mo->angle + 90*ANG1, 2*mapobjectscale); + P_Thrust(pmo, mo->angle + ANGLE_90, 2*mapobjectscale); p->rideroidrollangle += ANG1*3; if (p->rideroidrollangle > ANG1*25) @@ -323,15 +364,20 @@ void Obj_RideroidThink(mobj_t *mo) 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); + /*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); + + if (mo->angle > ANGLE_90 && mo->angle < ANGLE_270) + P_Thrust(pmo, mo->angle - ANGLE_90, RIDEROIDMAXADD*6*mapobjectscale); + else + P_Thrust(pmo, mo->angle + ANGLE_90, RIDEROIDMAXADD*6*mapobjectscale); + xthreshold = pmo->momx - basemomx; ythreshold = pmo->momy - basemomy; @@ -489,7 +535,7 @@ void Obj_RideroidNodeThink(mobj_t *mo) rd->angle = players[i].rideroidangle; P_SetTarget(&rd->target, pmo); - //S_StartSound(rd, sfx_ridr1); + S_StartSound(rd, sfx_ridr1); //CONS_Printf("rd pull\n"); diff --git a/src/p_map.c b/src/p_map.c index 92a2a65d4..25e1b6178 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1877,7 +1877,14 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) else if (shouldCollide == 2) return BMIT_CONTINUE; // force no collide } - + + // a bit of a hacky behaviour, but not that I know where else it would go. + if (tm.thing->type == MT_RIDEROID + && tm.blockingline->flags & ML_TFERLINE) + { + Obj_getPlayerOffRideroid(tm.thing); + } + if (!ld->backsector) // one sided line { if (P_PointOnLineSide(tm.thing->x, tm.thing->y, ld)) diff --git a/src/sounds.c b/src/sounds.c index 18bfa26d9..73e292e4e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1210,6 +1210,11 @@ sfxinfo_t S_sfx[NUMSFX] = {"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam + {"ridr1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boarding Rideroid"}, // Rideroid Activation + {"ridr2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Diveroll + {"ridr3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rideroid Loop + {"ridr4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Leaving Rideroid + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 35e530be3df2dcb2c87ba4838211014a61428e3e Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 13:47:39 +0200 Subject: [PATCH 05/39] LSZ bungee object/variable definitions --- src/d_player.h | 5 +++++ src/deh_tables.c | 2 ++ src/info.c | 27 +++++++++++++++++++++++++++ src/info.h | 2 ++ src/p_saveg.c | 4 ++++ 5 files changed, 40 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index 85be7c772..316b55c05 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -730,6 +730,11 @@ struct player_t fixed_t rdaddmomy; fixed_t rdaddmomz; + //////////// + // bungee // + //////////// + UINT8 bungee; // constants are defined with the object file for the bungee. + // SINT8 lives; diff --git a/src/deh_tables.c b/src/deh_tables.c index 0749e1665..a49383b8b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5827,6 +5827,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_RIDEROID", "MT_RIDEROIDNODE", + + "MT_LSZ_BUNGEE", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index a8c684a0e..39f3695a8 100644 --- a/src/info.c +++ b/src/info.c @@ -30442,6 +30442,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_NOCLIP, // flags S_NULL // raisestate }, + + { // MT_LSZ_BUNGEE + 3440, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 127*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SPECIAL, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index d364efc36..f8f003468 100644 --- a/src/info.h +++ b/src/info.h @@ -7026,6 +7026,8 @@ typedef enum mobj_type MT_RIDEROID, MT_RIDEROIDNODE, + MT_LSZ_BUNGEE, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/p_saveg.c b/src/p_saveg.c index 4af1c0b33..12ddd959e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -563,6 +563,8 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEFIXED(save->p, players[i].rdaddmomy); WRITEFIXED(save->p, players[i].rdaddmomz); + WRITEUINT8(save->, players[i].bungee); + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -1046,6 +1048,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].rdaddmomx = READFIXED(save->p); players[i].rdaddmomy = READFIXED(save->p); players[i].rdaddmomz = READFIXED(save->p); + + players[i].bungee = READUINT8(save->p); // respawnvars_t players[i].respawn.state = READUINT8(save->p); From ea8e87117680d3679350730dfc2ec01f52ad3d58 Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 14:42:39 +0200 Subject: [PATCH 06/39] LSZ bungee: first pass --- src/k_kart.c | 7 ++- src/k_objects.h | 3 + src/objects/CMakeLists.txt | 1 + src/objects/bungee.c | 120 +++++++++++++++++++++++++++++++++++++ src/p_inter.c | 4 ++ src/p_saveg.c | 2 +- 6 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 src/objects/bungee.c diff --git a/src/k_kart.c b/src/k_kart.c index e4459385b..d3aaf455b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11833,7 +11833,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_KartDrift(player, onground); K_KartSpindash(player); - if (onground == false) + if (onground == false + && !player->bungee // if this list of condition ever gets bigger, maybe this should become a function. + ) { K_AirFailsafe(player); } @@ -11841,8 +11843,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->pflags &= ~PF_AIRFAILSAFE; } - + Obj_RingShooterInput(player); + Obj_playerBungeeThink(player); } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/k_objects.h b/src/k_objects.h index 432063383..6166dc279 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -231,6 +231,9 @@ void Obj_RideroidNodeSpawn(mobj_t *mo); void Obj_RideroidNodeThink(mobj_t *mo); void Obj_getPlayerOffRideroid(mobj_t *mo); // used in p_map.c to get off of em when passing transfer lines. +/* LSZ Bungee */ +void Obj_BungeeSpecial(mobj_t *mo, player_t *p); // used when the player touches the bungee, to be used in p_inter.c +void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee. The bungee is to be stored in p->mo->tracer. #ifdef __cplusplus } // extern "C" diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 366a0a0f7..ee7c9df2c 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -30,4 +30,5 @@ target_sources(SRB2SDL2 PRIVATE emerald.c checkpoint.cpp rideroid.c + bungee.c ) diff --git a/src/objects/bungee.c b/src/objects/bungee.c new file mode 100644 index 000000000..1834cadcf --- /dev/null +++ b/src/objects/bungee.c @@ -0,0 +1,120 @@ +// 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 bungee.c +/// \brief Leaf Storm bungee interaction/behaviour code to be used in other files. + +#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 BUNGEE_NONE 0 +#define BUNGEE_LATCH 1 +#define BUNGEE_LAUNCH 2 + +// Touching the bungee, used in p_inter.c +void Obj_BungeeSpecial(mobj_t *mo, player_t *p) +{ + + mobj_t *latch; + + if (p->bungee || P_IsObjectOnGround(p->mo) || p->springstars) + return; + + P_InstaThrust(p->mo, 0, 0); + p->bungee = BUNGEE_LATCH; + p->mo->flags |= MF_NOCLIPTHING; // prevent players from bumping if they latch onto the same bungee. + p->pflags |= PF_NOFASTFALL; // didn't know this flag existed but it's very convenient!! + + latch = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK); + P_SetMobjState(latch, S_INVISIBLE); + latch->angle = mo->angle; + + S_StartSound(mo, sfx_s3k5a); + P_SetTarget(&p->mo->tracer, latch); + + return; +} + +// this is the thinker to call on the player when they get bungee'd. +void Obj_playerBungeeThink(player_t *p) +{ + + mobj_t *bungee = p->mo->tracer; + UINT8 i; + + // someone removed it + if (!bungee || !P_MobjWasRemoved(bungee)) + return; + + bungee->tics = 4; // we set this to a low value so that it despawns if the player vanishes for some reason. + + if (p->bungee == BUNGEE_LATCH) + { + // rr has super high gravity which gets in the way. + p->mo->flags |= MF_NOGRAVITY; + p->mo->momz = (p->mo->momz*9)/10; + + if (abs(p->mo->momz) < 6*mapobjectscale) + { + p->bungee = BUNGEE_LAUNCH; + p->mo->momz = P_MobjFlip(p->mo)*mapobjectscale; + S_StartSound(p->mo, sfx_s3k81); + } + } + else if (p->bungee == BUNGEE_LAUNCH) + { + p->mo->momz = (p->mo->momz*12)/10; + + // if we go above/below (depending on our flip flags) the bungee, release us! + if ((p->mo->eflags & MFE_VERTICALFLIP && p->mo->z < bungee->z) + || (!(p->mo->eflags & MFE_VERTICALFLIP) && p->mo->z > bungee->z )) + { + + p->mo->flags &= ~MF_NOGRAVITY; + p->mo->flags &= ~MF_NOCLIPTHING; + p->mo->pflags &= ~PF_NOFASTFALL; + p->bungee = BUNGEE_NONE; + P_InstaThrust(p->mo, bungee->angle, p->mo->momz/8); + p->mo->momz = (p->mo->momz*3)/4; + + p->springstars = TICRATE; // these are used as a buffer not to latch to vines again. + p->springcolor = SKINCOLOR_EMERALD; + + P_RemoveMobj(bungee); + P_SetTarget(&p->mo->tracer, NULL); + return; + } + } + + // basic visuals (but hey they work fine enough!) + for (i=0; i<8; i++) + { + fixed_t xpos = -(bungee->x - p->mo->x) /8 *i; + fixed_t ypos = -(bungee->y - p->mo->y) /8 *i; + fixed_t zpos = -(bungee->z - p->mo->z) /8 *i; + + mobj_t *seg = P_SpawnMobj(bungee->x + xpos, bungee->y + ypos, bungee->z + zpos, MT_THOK); + + P_SetScale(seg, mapobjectscale/3); + seg->color = SKINCOLOR_EMERALD; + seg->fuse = 2; + } +} \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index ffb4cff53..135b5d245 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -757,6 +757,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } + + case MT_LSZ_BUNGEE: + Obj_BungeeSpecial(special, player); + return; // CTF Flags case MT_REDFLAG: diff --git a/src/p_saveg.c b/src/p_saveg.c index 12ddd959e..e09b3fcf2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -563,7 +563,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEFIXED(save->p, players[i].rdaddmomy); WRITEFIXED(save->p, players[i].rdaddmomz); - WRITEUINT8(save->, players[i].bungee); + WRITEUINT8(save->p, players[i].bungee); // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); From 85a103e743eca9295f0a4949809b04f74dc9074b Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 14:46:02 +0200 Subject: [PATCH 07/39] Fix warnings in rideroid.c that popped up after I unfucked my compile flags --- src/objects/rideroid.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index bd3600693..59fb34f5b 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -118,7 +118,7 @@ static fixed_t Obj_rideroidLerp(INT32 start, INT32 finish, INT32 percent) static void Obj_rideroidTrail(mobj_t *mo) { mobj_t *pmo = mo->target; - player_t *p; + player_t *p = NULL; UINT8 i, j; @@ -456,9 +456,11 @@ void Obj_RideroidNodeSpawn(mobj_t *mo) for (i = 0; i < 2; i++) { - angle_t ang = mo->angle + (i)*180*ANG1; + angle_t ang = mo->angle + (i)*180; fixed_t zpos = mo->z + 64*mapobjectscale + mapobjectscale*96*i; + ang *= ANG1; // this has to be done here or the warning prevents the compile, we don't care about overflowing here. + for (j = 0; j < 7; j++) { fixed_t xpos = mo->x + FixedMul(radius, FINECOSINE(ang>>ANGLETOFINESHIFT)); From 9b432381c66b71263e6e3eb92548d5ac650d3faa Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 15:03:45 +0200 Subject: [PATCH 08/39] Finalize Bungee hardcode --- src/k_kart.c | 4 +++- src/objects/bungee.c | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index d3aaf455b..e4e155b7d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11845,7 +11845,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } Obj_RingShooterInput(player); - Obj_playerBungeeThink(player); + + if (player->bungee) + Obj_playerBungeeThink(player); } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/objects/bungee.c b/src/objects/bungee.c index 1834cadcf..91f026545 100644 --- a/src/objects/bungee.c +++ b/src/objects/bungee.c @@ -49,8 +49,6 @@ void Obj_BungeeSpecial(mobj_t *mo, player_t *p) S_StartSound(mo, sfx_s3k5a); P_SetTarget(&p->mo->tracer, latch); - - return; } // this is the thinker to call on the player when they get bungee'd. @@ -61,7 +59,7 @@ void Obj_playerBungeeThink(player_t *p) UINT8 i; // someone removed it - if (!bungee || !P_MobjWasRemoved(bungee)) + if (!bungee || P_MobjWasRemoved(bungee)) return; bungee->tics = 4; // we set this to a low value so that it despawns if the player vanishes for some reason. @@ -90,7 +88,7 @@ void Obj_playerBungeeThink(player_t *p) p->mo->flags &= ~MF_NOGRAVITY; p->mo->flags &= ~MF_NOCLIPTHING; - p->mo->pflags &= ~PF_NOFASTFALL; + p->pflags &= ~PF_NOFASTFALL; p->bungee = BUNGEE_NONE; P_InstaThrust(p->mo, bungee->angle, p->mo->momz/8); p->mo->momz = (p->mo->momz*3)/4; @@ -115,6 +113,7 @@ void Obj_playerBungeeThink(player_t *p) P_SetScale(seg, mapobjectscale/3); seg->color = SKINCOLOR_EMERALD; + seg->frame = 0; seg->fuse = 2; } } \ No newline at end of file From 42cbb93ca240bd5215fc7056a5a16448e903a99f Mon Sep 17 00:00:00 2001 From: Lat Date: Wed, 20 Sep 2023 16:33:07 +0200 Subject: [PATCH 09/39] Hardcode Leaf Storm Eggman balls --- src/deh_tables.c | 2 + src/info.c | 58 +++++++++++++++- src/info.h | 4 ++ src/k_objects.h | 4 ++ src/objects/CMakeLists.txt | 1 + src/objects/eggball.c | 134 +++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 8 +++ 7 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/objects/eggball.c diff --git a/src/deh_tables.c b/src/deh_tables.c index a49383b8b..d9e735ac8 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5829,6 +5829,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_RIDEROIDNODE", "MT_LSZ_BUNGEE", + "MT_LSZ_EGGBALLSPAWNER", + "MT_LSZ_EGGBALL", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 39f3695a8..de181d9ed 100644 --- a/src/info.c +++ b/src/info.c @@ -898,6 +898,9 @@ char sprnames[NUMSPRITES + 1][5] = "RDRC", "RDRL", + // leaf storm egg ball. + "LSZB", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5423,7 +5426,6 @@ state_t states[NUMSTATES] = {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON - }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -30469,6 +30471,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_SPECIAL, // flags S_NULL // raisestate }, + + { // MT_LSZ_EGGBALLSPAWNER + 3443, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_LSZ_EGGBALL + -1, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + DMG_TUMBLE, // mass + 0, // damage + sfx_None, // activesound + MF_PAIN, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index f8f003468..8a2447854 100644 --- a/src/info.h +++ b/src/info.h @@ -1451,6 +1451,8 @@ typedef enum sprite SPR_RDRC, SPR_RDRL, + SPR_LSZB, // eggman ball. + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -7027,6 +7029,8 @@ typedef enum mobj_type MT_RIDEROIDNODE, MT_LSZ_BUNGEE, + MT_LSZ_EGGBALLSPAWNER, + MT_LSZ_EGGBALL, MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, diff --git a/src/k_objects.h b/src/k_objects.h index 6166dc279..d67299f84 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -235,6 +235,10 @@ void Obj_getPlayerOffRideroid(mobj_t *mo); // used in p_map.c to get off of em w void Obj_BungeeSpecial(mobj_t *mo, player_t *p); // used when the player touches the bungee, to be used in p_inter.c void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee. The bungee is to be stored in p->mo->tracer. +/* LSZ Balls */ +void Obj_EggBallSpawnerThink(mobj_t *mo); +void Obj_EggBallThink(mobj_t *mo); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index ee7c9df2c..1d2156b87 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -31,4 +31,5 @@ target_sources(SRB2SDL2 PRIVATE checkpoint.cpp rideroid.c bungee.c + eggball.c ) diff --git a/src/objects/eggball.c b/src/objects/eggball.c new file mode 100644 index 000000000..0d9f684f5 --- /dev/null +++ b/src/objects/eggball.c @@ -0,0 +1,134 @@ +// 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 eggball.c +/// \brief Leaf Storm giant Eggman Balls. And their spawner. Yes, that sounds horribly wrong. No, I'm not changing it. + +#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 BALLMINSPAWNTIME 3 +#define BALLMAXSPAWNTIME 5 + +// spawns balls every BALLMINSPAWNTIME to BALLMAXSPAWNTIME seconds. +void Obj_EggBallSpawnerThink(mobj_t *mo) +{ + + if (!mo->extravalue1) + { + mobj_t *ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_LSZ_EGGBALL); + ball->angle = mo->angle; + P_SetScale(ball, 6*mapobjectscale); + + mo->extravalue1 = P_RandomRange(PR_FUZZ, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); + } + mo->extravalue1--; +} + +// ball thinker, it's mostly for particles and some bouncing n stuff to make em fancy. +// vars: +// threshold -> prevmomz +// movedir -> prevz + +void Obj_EggBallThink(mobj_t *mo) +{ + + P_SetScale(mo, 6*mapobjectscale); + + if (mo->eflags & MFE_JUSTHITFLOOR + && mo->threshold) + { + if (mo->threshold < -10*mapobjectscale) + { + UINT8 i; + + mo->momz = (fixed_t)(-mo->threshold)/8; + + for (i=0; i<16; i++) + { + angle_t an = ANG1; + mobj_t *dust = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DRIFTDUST); + P_SetScale(dust, mapobjectscale*3); + P_InstaThrust(dust, (360/16)*an*i, mapobjectscale*24); // the angle thing is to avoid a warning due to overflows. + dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + } + + S_StartSound(mo, sfx_s3k59); + + P_StartQuakeFromMobj(FRACUNIT*20, 6, 512 * mapobjectscale, mo); + + } + } + + if (!mo->extravalue1) + { + if (P_IsObjectOnGround(mo)) + { + mo->extravalue1 = 1; + mo->cusval = 24*mapobjectscale; + mo->movedir = mo->z; + mo->sprite = SPR_LSZB; + } + } + else + { + if (P_IsObjectOnGround(mo) && mo->extravalue2 &1) + { + fixed_t dx = mo->x + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momx*2; + fixed_t dy = mo->y + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momy*2; + fixed_t dz = mo->z; + + mobj_t *dust = P_SpawnMobj(dx, dy, dz, MT_DRIFTDUST); + P_SetScale(dust, mapobjectscale*3); + dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + dust->destscale = mapobjectscale*8; + } + + P_InstaThrust(mo, mo->angle, mo->cusval); + mo->extravalue2 += 1; + mo->frame = mo->extravalue2 % (24 * 2) / 2; // 24 is for frame Y. + + // build up speed + if (P_IsObjectOnGround(mo)) + { + if (mo->eflags & MFE_VERTICALFLIP) + { + if (mo->z > (fixed_t)mo->movedir) + { + mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16); + } + } + else + { + if (mo->z < (fixed_t)mo->movedir) + { + mo->cusval += max(mapobjectscale/32, abs(mo->z - (fixed_t)mo->movedir)/16); + } + } + } + + mo->movedir = mo->z; + } + mo->threshold = mo->momz; + + if (P_CheckDeathPitCollide(mo)) + P_RemoveMobj(mo); +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index a17e1eef7..60828fafe 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9646,7 +9646,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_RIDEROIDNODE: Obj_RideroidNodeThink(mobj); break; + + case MT_LSZ_EGGBALLSPAWNER: + Obj_EggBallSpawnerThink(mobj); + break; + case MT_LSZ_EGGBALL: + Obj_EggBallThink(mobj); + break; + default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); From 6ff02ab075c736b8fa9590f8a3f62f7e318518b9 Mon Sep 17 00:00:00 2001 From: Lat Date: Thu, 21 Sep 2023 08:08:33 +0200 Subject: [PATCH 10/39] Change Rideroid starting speed back to full value --- src/objects/rideroid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 59fb34f5b..768318a94 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -528,7 +528,7 @@ void Obj_RideroidNodeThink(mobj_t *mo) 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; + players[i].rideroidspeed = RIDEROIDSPEED; P_SetTarget(&pmo->tracer, mo); From 02409c554060c4e7e5dfbedf4f6a9ab91bf252aa Mon Sep 17 00:00:00 2001 From: Lat Date: Thu, 21 Sep 2023 09:24:15 +0200 Subject: [PATCH 11/39] Define DLZ objects/player variables --- src/d_player.h | 21 ++++++ src/deh_tables.c | 12 ++++ src/info.c | 174 +++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 18 +++++ src/p_saveg.c | 28 ++++++++ 5 files changed, 253 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index e0a0bc654..ad2bb6965 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -737,6 +737,27 @@ struct player_t //////////// UINT8 bungee; // constants are defined with the object file for the bungee. + //////////////////// + // dead line zone // + //////////////////// + // hovers + tic_t lasthover; // used for the hover mobjs + + // rockets + boolean dlzrocket; // true if latched onto a dlz rocket. + angle_t dlzrocketangle; // current travel angle with the rocket. + angle_t dlzrocketanglev; // current vertical travel angle with the rocket. + fixed_t dlzrocketspd; // current rocket travel speed. + + // seasaws (variables are shared with other seasaw-like objects) + boolean seasaw; // true if using a seasaw + tic_t seasawcooldown; // cooldown to avoid triggering the same seasaw over and over + fixed_t seasawdist; // distance from the center of the seasaw when latched. + angle_t seasawangle; // angle from the center of the seasaw when latched. + angle_t seasawangleadd; // used to spin the seasaw + boolean seasawdir; // flips or not seasaw rotation + + // SINT8 lives; diff --git a/src/deh_tables.c b/src/deh_tables.c index 5cb5b246d..52a11ea1c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4674,6 +4674,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_RIDEROID", "S_RIDEROID_ICON", + + "S_DLZHOVER", + "S_DLZROCKET_L", + "S_DLZROCKET_R", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -5833,6 +5837,14 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_LSZ_BUNGEE", "MT_LSZ_EGGBALLSPAWNER", "MT_LSZ_EGGBALL", + + "MT_DLZ_HOVER", + "MT_DLZ_ROCKET", + "MT_DLZ_SEASAW_SPAWN", + "MT_DLZ_SEASAW_HITBOX", + "MT_DLZ_SEASAW_VISUAL", + "MT_DLZ_RINGVACCUM", + "MT_DLZ_SUCKEDRING", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index dc82be30b..540d40537 100644 --- a/src/info.c +++ b/src/info.c @@ -901,6 +901,12 @@ char sprnames[NUMSPRITES + 1][5] = // leaf storm egg ball. "LSZB", + // Dead Line Zone + "DLZH", + "DLZR", + "DLZS", + "DLZA", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5429,6 +5435,12 @@ state_t states[NUMSTATES] = {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON + + {SPR_DLZH, 0, -1, {NULL}, 0, 0, S_DLZHOVER}, // S_DLZHOVER + + {SPR_DLZR, 0, -1, {NULL}, 0, 0, S_DLZROCKET_L}, // S_DLZROCKET_L + {SPR_DLZR, 1, -1, {NULL}, 0, 0, S_DLZROCKET_R}, // S_DLZROCKET_R + }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -30528,6 +30540,168 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_PAIN, // flags S_NULL // raisestate }, + + { // MT_DLZ_HOVER, + 3430, // doomednum + S_DLZHOVER, // 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 + 0, // speed + 100*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SOLID, // flags + S_NULL // raisestate + }, + + { // MT_DLZ_ROCKET, + 3431, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 100*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_SPECIAL, // flags + S_NULL // raisestate + }, + + { // MT_DLZ_SEASAW_SPAWN, + 3432, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + 0, // flags + S_NULL // raisestate + }, + + { // MT_DLZ_SEASAW_HITBOX, + -1, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 8*FRACUNIT, // radius + 40*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID, // flags + S_NULL // raisestate + }, + + { // MT_DLZ_SEASAW_VISUAL, + -1, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 40*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_DLZ_RINGVACCUM, + 3443, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 96*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index 8329c826d..1db640ed3 100644 --- a/src/info.h +++ b/src/info.h @@ -1453,6 +1453,11 @@ typedef enum sprite SPR_LSZB, // eggman ball. + SPR_DLZH, // DLZ Hover + SPR_DLZR, // DLZ Rocket + SPR_DLZS, // DLZ Seasaw + SPR_DLZA, // Helper arrows for rocket + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -5856,6 +5861,11 @@ typedef enum state S_RIDEROID, S_RIDEROID_ICON, + // dead line zone + S_DLZHOVER, + S_DLZROCKET_L, + S_DLZROCKET_R, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -7034,6 +7044,14 @@ typedef enum mobj_type MT_LSZ_EGGBALLSPAWNER, MT_LSZ_EGGBALL, + MT_DLZ_HOVER, + MT_DLZ_ROCKET, + MT_DLZ_SEASAW_SPAWN, + MT_DLZ_SEASAW_HITBOX, + MT_DLZ_SEASAW_VISUAL, + MT_DLZ_RINGVACCUM, + MT_DLZ_SUCKEDRING, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/p_saveg.c b/src/p_saveg.c index 656a92190..19d03b8b2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -565,6 +565,20 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].bungee); + WRITEUINT32(save->p, players[i].lasthover); + + WRITEUINT8(save->p, players[i].dlzrocket); + WRITEUINT32(save->p, players[i].dlzrocketangle); + WRITEUINT32(save->p, players[i].dlzrocketanglev); + WRITEUINT32(save->p, players[i].dlzrocketspd); + + WRITEUINT8(save->p, players[i].seasaw); + WRITEUINT32(save->p, players[i].seasawcooldown); + WRITEUINT32(save->p, players[i].seasawdist); + WRITEUINT32(save->p, players[i].seasawangle); + WRITEUINT32(save->p, players[i].seasawangleadd); + WRITEUINT8(save->p, players[i].seasawdir); + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -1051,6 +1065,20 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].rdaddmomz = READFIXED(save->p); players[i].bungee = READUINT8(save->p); + + players[i].lasthover = READUINT32(save->p); + + players[i].dlzrocket = READUINT8(save->p); + players[i].dlzrocketangle = READUINT32(save->p); + players[i].dlzrocketanglev = READUINT32(save->p); + players[i].dlzrocketspd = READUINT32(save->p); + + players[i].seasaw = READUINT8(save->p); + players[i].seasawcooldown = READUINT32(save->p); + players[i].seasawdist = READUINT32(save->p); + players[i].seasawangle = READUINT32(save->p); + players[i].seasawangleadd = READUINT32(save->p); + players[i].seasawdir = READUINT8(save->p); // respawnvars_t players[i].respawn.state = READUINT8(save->p); From fb91a9a0f7b4276784cbdd3bbc6543a20e42e408 Mon Sep 17 00:00:00 2001 From: Lat Date: Thu, 21 Sep 2023 15:42:10 +0200 Subject: [PATCH 12/39] DLZ rocket hardcode --- src/d_player.h | 4 +- src/k_kart.c | 3 + src/k_objects.h | 6 ++ src/objects/CMakeLists.txt | 1 + src/objects/dlzrocket.c | 190 +++++++++++++++++++++++++++++++++++++ src/p_inter.c | 6 +- src/p_map.c | 12 ++- src/p_mobj.c | 5 +- src/p_saveg.c | 12 +-- 9 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 src/objects/dlzrocket.c diff --git a/src/d_player.h b/src/d_player.h index ad2bb6965..dd5040d64 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -744,9 +744,9 @@ struct player_t tic_t lasthover; // used for the hover mobjs // rockets - boolean dlzrocket; // true if latched onto a dlz rocket. + tic_t dlzrocket; // counts up as we stay on a rocket. angle_t dlzrocketangle; // current travel angle with the rocket. - angle_t dlzrocketanglev; // current vertical travel angle with the rocket. + INT32 dlzrocketanglev; // current vertical travel angle with the rocket. signed instead of angle_t. fixed_t dlzrocketspd; // current rocket travel speed. // seasaws (variables are shared with other seasaw-like objects) diff --git a/src/k_kart.c b/src/k_kart.c index de0575c70..f68772976 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11845,6 +11845,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->bungee) Obj_playerBungeeThink(player); + + if (player->dlzrocket) + Obj_playerDLZRocket(player); } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/k_objects.h b/src/k_objects.h index 5e1b054aa..c788f314e 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -247,6 +247,12 @@ void Obj_playerBungeeThink(player_t *p); // player interaction with the bungee void Obj_EggBallSpawnerThink(mobj_t *mo); void Obj_EggBallThink(mobj_t *mo); +/* DLZ Rockets */ +void Obj_DLZRocketSpawn(mobj_t *mo); +void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p); // touch activation +void Obj_playerDLZRocket(player_t *p); // player looping thinker +void Obj_DLZRocketDismount(player_t *p); // used in p_map.c to get off the rocket when we cross transfer lines. + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 7abf26105..22f846836 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -32,5 +32,6 @@ target_sources(SRB2SDL2 PRIVATE rideroid.c bungee.c eggball.c + dlzrocket.c shadow.cpp ) diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c new file mode 100644 index 000000000..c45e9f60c --- /dev/null +++ b/src/objects/dlzrocket.c @@ -0,0 +1,190 @@ +// 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 dlzrocket.c +/// \brief Dead Line Zone free flight rockets! They cool af doe. + +#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 DLZROCKETDIST 96 +#define DLZROCKETSPEED 80 +#define DLZROCKETTURNSPEED ((ANG1*3)/2) +#define DLZROCKETVERTSPEED (ANG1) +#define DLZROCKETMAXVERT (ANG1*60) + +void Obj_DLZRocketSpawn(mobj_t *mo) +{ + UINT8 i; + angle_t an = mo->angle + ANGLE_90; + + for (i = 0; i < 2; i++) + { + fixed_t x = mo->x + FixedMul(mapobjectscale, DLZROCKETDIST*FINECOSINE(an>>ANGLETOFINESHIFT)); + fixed_t y = mo->y + FixedMul(mapobjectscale, DLZROCKETDIST*FINESINE(an>>ANGLETOFINESHIFT)); + + mobj_t *r = P_SpawnMobj(x, y, mo->z, MT_THOK); + P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R); + P_SetScale(r, (mapobjectscale*3)/2); + r->angle = mo->angle; + r->tics = -1; + + an += ANGLE_180; + } +} + +void Obj_DLZRocketDismount(player_t *p) +{ + // we aren't mounted on one. + if (!p->dlzrocket) + return; + + p->dlzrocket = 0; + K_SpawnMineExplosion(p->mo, p->mo->color, 3); + S_StartSound(p->mo, sfx_s3k4e); +} + +// touching the rocket, initialize player vars etc... +void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p) +{ + if (p->dlzrocket) // already on one, don't bother resetting, duh. + return; + + p->mo->z = mo->z + 16*P_MobjFlip(p->mo)*mapobjectscale; + P_SetPlayerAngle(p->mo->player, mo->angle); + p->dlzrocket = true; + p->dlzrocketangle = mo->angle; + p->dlzrocketanglev = 0; + p->dlzrocketspd = DLZROCKETSPEED; + + p->spinouttimer = 0; + p->wipeoutslow = 0; + + S_StartSound(mo, sfx_s262); +} + +void Obj_playerDLZRocket(player_t *p) +{ + + fixed_t maxspd = DLZROCKETSPEED; + angle_t visangle; + UINT8 i, j; + + p->dlzrocket++; + + // helper arrows at the start of the ride to tell players they can move freely + if (p->dlzrocket < TICRATE*2 + && leveltime%10 < 5) + { + mobj_t *arr = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK); + arr->sprite = SPR_DLZA; + arr->frame = FF_FULLBRIGHT; + P_SetScale(arr, 2*mapobjectscale); + arr->tics = 2; + } + + + // calc max speed + if (p->ringboost) + maxspd += 10; + + // set player speed + if (p->dlzrocketspd < maxspd) + p->dlzrocketspd++; + else if (p->dlzrocketspd > maxspd) + p->dlzrocket--; + + + // so long as PF_STASIS is applied, let the angle be overwritten freely. + // this is used by seasaws but can be used for misc modding purposes too. + if (p->pflags & PF_STASIS) + p->dlzrocketangle = p->mo->angle; + else + { + SINT8 turndir = 0; + P_SetPlayerAngle(p->mo->player, p->dlzrocketangle); + + if (p->cmd.turning > 0) + turndir = 1; + else if (p->cmd.turning < 0) + turndir = -1; + + p->dlzrocketangle += turndir*DLZROCKETTURNSPEED; + + if (p->cmd.throwdir > 0) + p->dlzrocketanglev = min(DLZROCKETMAXVERT, p->dlzrocketanglev + DLZROCKETVERTSPEED); + else if (p->cmd.throwdir < 0) + p->dlzrocketanglev = max(-DLZROCKETMAXVERT, p->dlzrocketanglev - DLZROCKETVERTSPEED); + + } + + // angle correction on ceilings (THIS CODE LOOKS AWFUL AND IT CAN PROBABLY BE DONE BETTER......) + if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && (p->mo->z+p->mo->height >= p->mo->ceilingz)) + || (p->mo->eflags & MFE_VERTICALFLIP && p->mo->z <= p->mo->floorz)) + if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && p->dlzrocketanglev > 0) + || (p->mo->eflags & MFE_VERTICALFLIP && p->dlzrocketanglev < 0)) + p->dlzrocketanglev = 0; + + + if (!(p->pflags & PF_STASIS)) + { + angle_t van = p->dlzrocketanglev /4; + P_InstaThrust(p->mo, p->dlzrocketangle, FixedMul(mapobjectscale, p->dlzrocketspd*FINECOSINE(van>>ANGLETOFINESHIFT))); + p->mo->momz = FixedMul(mapobjectscale, p->dlzrocketspd*FINESINE((angle_t)p->dlzrocketanglev>>ANGLETOFINESHIFT)); + } + + if (leveltime%4 == 0) + S_StartSound(p->mo, sfx_s1c8); + + // finally, visuals. + visangle = p->mo->angle + ANGLE_90; + + for (i = 0; i < 2; i++) + { + fixed_t x = p->mo->x + FixedMul(mapobjectscale, 56*FINECOSINE(visangle>>ANGLETOFINESHIFT)); + fixed_t y = p->mo->y + FixedMul(mapobjectscale, 56*FINESINE(visangle>>ANGLETOFINESHIFT)); + mobj_t *r = P_SpawnMobj(x, y, p->mo->z + 16*mapobjectscale, MT_THOK); + r->fuse = 2; + P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R); + P_SetScale(r, (mapobjectscale*3)/2); + r->angle = p->mo->angle; + + for (j = 0; j < 2; j++) + { + fixed_t xoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; + fixed_t yoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; + fixed_t soffs = P_RandomRange(PR_FUZZ, 0, 3); + + mobj_t *expl = P_SpawnMobj(r->x + xoffs, r->y + yoffs, r->z + xoffs, MT_THOK); + P_SetMobjState(expl, S_QUICKBOOM1+soffs); + expl->color = p->mo->color; + P_SetScale(expl, mapobjectscale); + expl->destscale = 2*mapobjectscale; + + } + visangle += ANGLE_180; + } + + if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL)) + || p->spinouttimer || p->wipeoutslow || p->tumbleHeight) + Obj_DLZRocketDismount(p); + +} \ No newline at end of file diff --git a/src/p_inter.c b/src/p_inter.c index 4be5b08f0..dc6df0844 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -820,7 +820,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_RAINBOWDASHRING: Obj_DashRingTouch(special, player); return; - + + case MT_DLZ_ROCKET: + Obj_DLZRocketSpecial(special, player); + return; + default: // SOC or script pickup P_SetTarget(&special->target, toucher); break; diff --git a/src/p_map.c b/src/p_map.c index 25e1b6178..e39c7fd29 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1879,10 +1879,16 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) } // a bit of a hacky behaviour, but not that I know where else it would go. - if (tm.thing->type == MT_RIDEROID - && tm.blockingline->flags & ML_TFERLINE) + if (tm.blockingline->flags & ML_TFERLINE) { - Obj_getPlayerOffRideroid(tm.thing); + if (tm.thing->type == MT_RIDEROID) + { + Obj_getPlayerOffRideroid(tm.thing); + } + else if (tm.thing->type == MT_PLAYER && tm.thing->player && tm.thing->player->dlzrocket) + { + Obj_DLZRocketDismount(tm.thing->player); + } } if (!ld->backsector) // one sided line diff --git a/src/p_mobj.c b/src/p_mobj.c index 80394d5af..f50e4e687 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11160,7 +11160,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_RIDEROIDNODE: Obj_RideroidNodeSpawn(mobj); - break; + break; + case MT_DLZ_ROCKET: + Obj_DLZRocketSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 19d03b8b2..0c3ff7596 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -567,9 +567,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].lasthover); - WRITEUINT8(save->p, players[i].dlzrocket); - WRITEUINT32(save->p, players[i].dlzrocketangle); - WRITEUINT32(save->p, players[i].dlzrocketanglev); + WRITEUINT32(save->p, players[i].dlzrocket); + WRITEANGLE(save->p, players[i].dlzrocketangle); + WRITEINT32(save->p, players[i].dlzrocketanglev); WRITEUINT32(save->p, players[i].dlzrocketspd); WRITEUINT8(save->p, players[i].seasaw); @@ -1068,9 +1068,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].lasthover = READUINT32(save->p); - players[i].dlzrocket = READUINT8(save->p); - players[i].dlzrocketangle = READUINT32(save->p); - players[i].dlzrocketanglev = READUINT32(save->p); + players[i].dlzrocket = READUINT32(save->p); + players[i].dlzrocketangle = READANGLE(save->p); + players[i].dlzrocketanglev = READINT32(save->p); players[i].dlzrocketspd = READUINT32(save->p); players[i].seasaw = READUINT8(save->p); From a565d923c0559195d7134e674774ecee5702d22b Mon Sep 17 00:00:00 2001 From: Lat Date: Fri, 22 Sep 2023 18:14:38 +0200 Subject: [PATCH 13/39] Hardcode these cursed seasaws --- src/d_player.h | 5 +- src/info.c | 2 +- src/k_kart.c | 3 + src/k_objects.h | 5 + src/objects/CMakeLists.txt | 1 + src/objects/dlzseasaw.c | 340 +++++++++++++++++++++++++++++++++++++ src/p_map.c | 10 +- src/p_mobj.c | 7 + src/p_saveg.c | 10 +- src/p_user.c | 2 +- 10 files changed, 376 insertions(+), 9 deletions(-) create mode 100644 src/objects/dlzseasaw.c diff --git a/src/d_player.h b/src/d_player.h index dd5040d64..9101e3dc7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -753,8 +753,9 @@ struct player_t boolean seasaw; // true if using a seasaw tic_t seasawcooldown; // cooldown to avoid triggering the same seasaw over and over fixed_t seasawdist; // distance from the center of the seasaw when latched. - angle_t seasawangle; // angle from the center of the seasaw when latched. - angle_t seasawangleadd; // used to spin the seasaw + INT32 seasawangle; // angle from the center of the seasaw when latched. + INT32 seasawangleadd; // used to spin the seasaw + INT32 seasawmoreangle; // used for reverse sesaws in DLZ. boolean seasawdir; // flips or not seasaw rotation diff --git a/src/info.c b/src/info.c index 540d40537..e17703b35 100644 --- a/src/info.c +++ b/src/info.c @@ -30672,7 +30672,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY, // flags + MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, diff --git a/src/k_kart.c b/src/k_kart.c index f68772976..ccf30d4bd 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -11848,6 +11848,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->dlzrocket) Obj_playerDLZRocket(player); + + if (player->seasawcooldown && !player->seasaw) + player->seasawcooldown--; } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/k_objects.h b/src/k_objects.h index c788f314e..a777c37fd 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -253,6 +253,11 @@ void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p); // touch activation void Obj_playerDLZRocket(player_t *p); // player looping thinker void Obj_DLZRocketDismount(player_t *p); // used in p_map.c to get off the rocket when we cross transfer lines. +/* DLZ Seasaw */ +void Obj_DLZSeasawSpawn(mobj_t *mo); +void Obj_DLZSeasawThink(mobj_t *mo); +void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 22f846836..70060bfb0 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -33,5 +33,6 @@ target_sources(SRB2SDL2 PRIVATE bungee.c eggball.c dlzrocket.c + dlzseasaw.c shadow.cpp ) diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c new file mode 100644 index 000000000..fe0e73dcd --- /dev/null +++ b/src/objects/dlzseasaw.c @@ -0,0 +1,340 @@ +// 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 dlzseasaw.c +/// \brief Dead Line Zone seasaw. Amplifies momentum in a stylish way... and hellish as far as code is concerned, heh! + +#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" + +// updates the seasaw's visuals and hitboxes using the hnext/hprev list. +static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) +{ + + mobj_t *ptr = mo; + mobj_t *ptrp = mo; + UINT8 i, j; + angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90; + + P_SetScale(mo, 2*mapobjectscale); + + if (mo->tracer && !P_MobjWasRemoved(mo->tracer)) + { + mo->tracer->tics = 3; + P_MoveOrigin(mo->tracer, mo->x, mo->y, mo->z); + P_SetScale(mo->tracer, mo->scale); + } + + + for (i = 0; i < 2; i++) + { + INT32 dist = 32; // visuals dist + INT32 hdist = 16; // hitbox dist + + // visuals + for (j = 0; j < 2; j++) + { + // get our mobj. + if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext)) + { + fixed_t x = mo->x + FixedMul(mo->scale, dist*FINECOSINE(visan>>ANGLETOFINESHIFT)); + fixed_t y = mo->y + FixedMul(mo->scale, dist*FINESINE(visan>>ANGLETOFINESHIFT)); + ptr = ptr->hnext; + + P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); + ptr->angle = visan; + ptr->tics = 3; + P_SetScale(ptr, mo->scale); + + if (ghostme && leveltime&1) + { + mobj_t *g = P_SpawnGhostMobj(ptr); + g->colorized = true; + g->color = mo->color; + g->fuse = 3; + } + + dist += 55; + } + } + + // hitboxes: + for (j = 0; j < 8; j++) + { + // get our mobj. + if (ptrp && !P_MobjWasRemoved(ptrp) && ptrp->hprev && !P_MobjWasRemoved(ptrp->hprev)) + { + + fixed_t x = mo->x + FixedMul(mo->scale, hdist*FINECOSINE(visan>>ANGLETOFINESHIFT)); + fixed_t y = mo->y + FixedMul(mo->scale, hdist*FINESINE(visan>>ANGLETOFINESHIFT)); + + ptrp = ptrp->hprev; + + P_SetOrigin(ptrp, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); // it's invisible so nobody cares about interpolating it. + ptrp->angle = visan; + ptrp->tics = 3; + + hdist += 16; + } + + } + + visan += ANGLE_180; + } +} + +// sets up seasaw spawn objects to update each frame later +void Obj_DLZSeasawSpawn(mobj_t *mo) +{ + mobj_t *pole; + mobj_t *ptr = mo; + mobj_t *ptrp = mo; + UINT8 i, j; + + // setup vars + mo->extravalue1 = (INT32)mo->angle; + + // center pole: + pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); + pole->tics = -1; + pole->sprite = SPR_DLZS; + pole->frame = 0; + P_SetTarget(&pole->target, mo); + P_SetTarget(&mo->tracer, pole); + + if (mo->eflags & MFE_VERTICALFLIP) + pole->eflags |= MFE_VERTICALFLIP; + + // spawn visuals / hitboxes. + for (i = 0; i < 2; i++) // for each side... + { + for (j = 0; j < 2; j++) // spawn the 2 visual papersprites on each side. + { + // right now we don't care if the objects are positionned properly. + + mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_VISUAL); + vis->sprite = SPR_DLZS; + vis->frame = (j+1)|FF_PAPERSPRITE; + vis->tics = -1; + + if (mo->eflags & MFE_VERTICALFLIP) + { + vis->eflags |= MFE_VERTICALFLIP; + vis->flags2 |= MF2_OBJECTFLIP; + } + + P_SetTarget(&vis->target, mo); + P_SetTarget(&ptr->hnext, vis); // save in an hnext list for updating later. + ptr = vis; + } + + for (j = 0; j < 8; j++) // spawn the 8 hitboxes on each side. + { + // right now we don't care if the objects are positionned properly. + + mobj_t *h = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_HITBOX); + h->extravalue1 = i; // keep track of which side we're on. + h->tics = -1; + + if (mo->eflags & MFE_VERTICALFLIP) + { + h->eflags |= MFE_VERTICALFLIP; + h->flags2 |= MF2_OBJECTFLIP; + } + + P_SetTarget(&h->target, mo); + P_SetTarget(&ptrp->hprev, h); // save in an hprev list for updating later. + ptrp = h; + } + } + + // update after spawning the objects so that they appear in the right spot when the map loads. + Obj_DLZSeasawUpdate(mo, false); +} + +static void Obj_DLZSeasawReset(mobj_t *mo) +{ + mo->extravalue1 = (INT32)mo->angle; + P_SetTarget(&mo->target, NULL); + Obj_DLZSeasawUpdate(mo, false); +} + +// main seasaw thinker. +void Obj_DLZSeasawThink(mobj_t *mo) +{ + boolean ghost = false; + SINT8 rot = 1; + fixed_t px, py; + + if (mo->target && !P_MobjWasRemoved(mo->target)) + { + mobj_t *t = mo->target; + player_t *p = t->player; // our target should always be a player, do NOT porceed if it isn't. + + if (!p) // untarget this instantly. + { + Obj_DLZSeasawReset(mo); + return; + } + + if (!mo->extravalue2) + rot = -1; + + // first half of the animation... + if (!p->seasawdir) + { + INT32 angleadd = ANG1*max(4, (mo->movefactor/3)/mapobjectscale) * rot; + + if (p->seasawangleadd > 175) + angleadd /= max(1, (p->seasawangleadd - 160)/8); + + mo->extravalue1 += angleadd; + p->seasawangle += angleadd; + + p->seasawangleadd += max(4, (mo->movefactor/3)/mapobjectscale); + P_SetPlayerAngle(p, (angle_t)(p->seasawangle + ANGLE_90*rot)); + //t->angle = p->seasawangle + ANGLE_90*rot; + + p->seasawdist++; + p->seasawdist = min(p->seasawdist, (160*mapobjectscale)/FRACUNIT); + + if (abs((angleadd)/ANG1 ) < 2) // if we get to 1, invert the rotation! + { + p->seasawdir = true; + p->seasawangleadd = 0; // reset, we're gonna do a full 360! + p->seasawmoreangle = p->seasawangleadd - 170; + S_StartSound(t, sfx_s3k88); + S_StartSound(t, sfx_s3ka2); + } + } + else + { + INT32 angleadd = (mo->cvmem*2 +1)*(-rot); + mo->cvmem++; + + p->seasawangleadd += abs(angleadd)/2; // for some reason i need to do this and i'm actually not sure why. + mo->extravalue1 += angleadd*ANG1; + p->seasawangle += angleadd*ANG1; + + P_SetPlayerAngle(p, (angle_t)(p->seasawangle - ANGLE_90*rot)); + ghost = true; + + if (p->seasawangleadd >= 340 + p->seasawmoreangle) + { + // reset everything and send the player zooming + Obj_DLZSeasawReset(mo); + + P_SetPlayerAngle(p, mo->angle); + P_MoveOrigin(t, t->x, t->y, t->z); // miscall that to set the position properly. + P_InstaThrust(t, mo->angle, mo->movefactor*3); // send the player flying at triple the speed they came at us with. + S_StartSound(t, sfx_cdfm62); + + p->seasawangleadd = 0; + p->seasawangle = 0; + p->seasawmoreangle = 0; + p->seasaw = false; + + Obj_DLZSeasawUpdate(mo, true); + return; + + } + } + // update the player + px = mo->x + p->seasawdist*FINECOSINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT); + py = mo->y + p->seasawdist*FINESINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT); + + P_MoveOrigin(t, px, py, mo->z + mapobjectscale*8); + } + else + Obj_DLZSeasawReset(mo); + + // finally, update the visuals. + Obj_DLZSeasawUpdate(mo, ghost); +} + +// ported just for convenience of not needing to rewrite the code to account for UINT32 angles... +// the precision loss hardly matters whatsoever. +static INT32 angtoint(angle_t a) +{ + return a/ANG1; +} + +// to use in mobjcollide and movemobjcollide just like the lua, woo. +// mo is the player's mo, mo2 is the seasaw hitbox. +void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) +{ + player_t *p = mo->player; + INT32 momangle; + boolean invert = false; + + // cooldown / respawning + if (p->seasawcooldown || p->respawn.timer) + return; + + // another player is already using the seasar + if (mo2->target && !P_MobjWasRemoved(mo2->target) && mo2->target->target && !P_MobjWasRemoved(mo2->target->target)) + return; + + // height checks + if (mo->z + mo->height < mo2->z) + return; + + if (mo->z > mo2->z + mo2->height) + return; + + // too slow. + if (p->speed < K_GetKartSpeed(p, false, false)/3) + return; + + + momangle = angtoint(R_PointToAngle2(0, 0, mo->momx, mo->momy)); + + //CONS_Printf("%d / %d -> %d\n", momangle, angtoint(mo2->target->angle), (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180))); + + // this depends on the side we hit the thing from. + if (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180) > 60) + { + mo2->target->angle += ANGLE_180; + mo2->target->extravalue1 += ANGLE_180; + invert = true; + } + + mo2->target->movefactor = p->speed; // keep the speed the player was going at. + mo2->target->extravalue2 = mo2->extravalue1; // which side of the pole are we on? + + // if inverted, then invert the value too. + if (invert) + mo2->target->extravalue2 = (!mo2->target->extravalue2) ? 1 : 0; + + P_SetTarget(&mo2->target->target, mo); + mo2->target->cvmem = 0; + + // set player vars now: + p->seasawdist = R_PointToDist2(mo->x, mo->y, mo2->target->x, mo2->target->y) /FRACUNIT; // distance from us to the center + p->seasawangle = (INT32)R_PointToAngle2(mo2->target->x, mo2->target->y, mo->x, mo->y); // angle from the center to us + p->seasawangleadd = 0; + p->seasawdir = false; + p->seasaw = true; + p->pflags |= PF_STASIS; + p->seasawcooldown = TICRATE/2; + + S_StartSound(mo, sfx_s3k88); +} \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index e39c7fd29..2bf453318 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -741,7 +741,15 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) } // SRB2kart 011617 - Colission[sic] code for kart items // - + + if (thing->type == MT_DLZ_SEASAW_HITBOX) + { + if (tm.thing->type == MT_PLAYER) + Obj_DLZSeasawCollide(tm.thing, thing); // all checks are performed in there. + + return BMIT_CONTINUE; + } + if (tm.thing->type == MT_INSTAWHIP) { if (tm.thing->z > thing->z + thing->height) diff --git a/src/p_mobj.c b/src/p_mobj.c index f50e4e687..1a2fb5c88 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9725,6 +9725,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_EggBallThink(mobj); break; + case MT_DLZ_SEASAW_SPAWN: + Obj_DLZSeasawThink(mobj); + break; + default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); @@ -11164,6 +11168,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_DLZ_ROCKET: Obj_DLZRocketSpawn(mobj); break; + case MT_DLZ_SEASAW_SPAWN: + Obj_DLZSeasawSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break; diff --git a/src/p_saveg.c b/src/p_saveg.c index 0c3ff7596..d9a6fc81b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -575,8 +575,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].seasaw); WRITEUINT32(save->p, players[i].seasawcooldown); WRITEUINT32(save->p, players[i].seasawdist); - WRITEUINT32(save->p, players[i].seasawangle); - WRITEUINT32(save->p, players[i].seasawangleadd); + WRITEINT32(save->p, players[i].seasawangle); + WRITEINT32(save->p, players[i].seasawangleadd); + WRITEINT32(save->p, players[i].seasawmoreangle); WRITEUINT8(save->p, players[i].seasawdir); // respawnvars_t @@ -1076,8 +1077,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].seasaw = READUINT8(save->p); players[i].seasawcooldown = READUINT32(save->p); players[i].seasawdist = READUINT32(save->p); - players[i].seasawangle = READUINT32(save->p); - players[i].seasawangleadd = READUINT32(save->p); + players[i].seasawangle = READINT32(save->p); + players[i].seasawangleadd = READINT32(save->p); + players[i].seasawmoreangle = READINT32(save->p); players[i].seasawdir = READUINT8(save->p); // respawnvars_t diff --git a/src/p_user.c b/src/p_user.c index 8f4dc5090..53e9201c9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3192,7 +3192,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall lookback = ( player->cmd.buttons & BT_LOOKBACK ); camspeed = cv_cam_speed[num].value; - camstill = cv_cam_still[num].value; + camstill = cv_cam_still[num].value || player->seasaw; // RR: seasaws lock the camera so that it isn't disorienting. camrotate = cv_cam_rotate[num].value; camdist = FixedMul(cv_cam_dist[num].value, cameraScale); camheight = FixedMul(cv_cam_height[num].value, cameraScale); From ca90d27e30558f40d40942318d9b47dacfb73040 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 11:00:00 +0200 Subject: [PATCH 14/39] Hardcode DLZ Hover thingies + rocket fixes --- src/k_objects.h | 6 +++- src/objects/CMakeLists.txt | 1 + src/objects/dlzothers.c | 69 ++++++++++++++++++++++++++++++++++++++ src/objects/dlzrocket.c | 10 ++++-- src/p_map.c | 8 +++++ src/p_mobj.c | 10 ++++-- 6 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 src/objects/dlzothers.c diff --git a/src/k_objects.h b/src/k_objects.h index a777c37fd..b76e64e4b 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -248,7 +248,7 @@ void Obj_EggBallSpawnerThink(mobj_t *mo); void Obj_EggBallThink(mobj_t *mo); /* DLZ Rockets */ -void Obj_DLZRocketSpawn(mobj_t *mo); +void Obj_DLZRocketThink(mobj_t *mo); void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p); // touch activation void Obj_playerDLZRocket(player_t *p); // player looping thinker void Obj_DLZRocketDismount(player_t *p); // used in p_map.c to get off the rocket when we cross transfer lines. @@ -258,6 +258,10 @@ void Obj_DLZSeasawSpawn(mobj_t *mo); void Obj_DLZSeasawThink(mobj_t *mo); void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2); +/* DLZ Hover */ +void Obj_DLZHoverSpawn(mobj_t *mo); +void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 70060bfb0..042a39f90 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -34,5 +34,6 @@ target_sources(SRB2SDL2 PRIVATE eggball.c dlzrocket.c dlzseasaw.c + dlzothers.c shadow.cpp ) diff --git a/src/objects/dlzothers.c b/src/objects/dlzothers.c new file mode 100644 index 000000000..887813b60 --- /dev/null +++ b/src/objects/dlzothers.c @@ -0,0 +1,69 @@ +// 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 dlzothers.c +/// \brief Dead Line Zone other objects (Hover + Ring Vaccum), they're small enough that we can just lump em together instead of having 2 more small files... + +#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" + +// Hover: +void Obj_DLZHoverSpawn(mobj_t *mo) +{ + P_SetScale(mo, mapobjectscale*4); + mo->destscale = mapobjectscale*4; +} + +void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2) +{ + player_t *p = mo->player; + + if (!p || p->lasthover == leveltime) + return; + + if (abs(mo->z - mo2->z) < 512*mapobjectscale) + { + // momz adjust + if (mo2->eflags & MFE_VERTICALFLIP) + { + if (mo->momz > -16*mapobjectscale) + { + mo->momz -= 8*mapobjectscale; + } + } + else + { + if (mo->momz < 16*mapobjectscale) + { + mo->momz += 8*mapobjectscale; + } + } + + // speed adjust + if (p->speed > K_GetKartSpeed(p, false, false)) + P_Thrust(mo, R_PointToAngle2(0, 0, -mo->momx, -mo->momy), mapobjectscale/16); + + if (!S_SoundPlaying(mo, sfx_s3kc6s)) + S_StartSound(mo, sfx_s3kc6s); + + p->lasthover = leveltime; + } +} \ No newline at end of file diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index c45e9f60c..153831d40 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -31,11 +31,14 @@ #define DLZROCKETVERTSPEED (ANG1) #define DLZROCKETMAXVERT (ANG1*60) -void Obj_DLZRocketSpawn(mobj_t *mo) +void Obj_DLZRocketThink(mobj_t *mo) { UINT8 i; angle_t an = mo->angle + ANGLE_90; + if (mo->extravalue1) + return; + for (i = 0; i < 2; i++) { fixed_t x = mo->x + FixedMul(mapobjectscale, DLZROCKETDIST*FINECOSINE(an>>ANGLETOFINESHIFT)); @@ -44,11 +47,14 @@ void Obj_DLZRocketSpawn(mobj_t *mo) mobj_t *r = P_SpawnMobj(x, y, mo->z, MT_THOK); P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R); P_SetScale(r, (mapobjectscale*3)/2); - r->angle = mo->angle; + r->destscale = (mapobjectscale*3)/2; + r->angle = mo->spawnpoint->angle*ANG1; r->tics = -1; an += ANGLE_180; } + + mo->extravalue1 = 1; } void Obj_DLZRocketDismount(player_t *p) diff --git a/src/p_map.c b/src/p_map.c index 2bf453318..7adcefcde 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -750,6 +750,14 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return BMIT_CONTINUE; } + if (thing->type == MT_DLZ_HOVER) + { + if (tm.thing->type == MT_PLAYER) + Obj_DLZHoverCollide(tm.thing, thing); + + return BMIT_CONTINUE; + } + if (tm.thing->type == MT_INSTAWHIP) { if (tm.thing->z > thing->z + thing->height) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1a2fb5c88..f5566be6c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9724,6 +9724,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_LSZ_EGGBALL: Obj_EggBallThink(mobj); break; + + case MT_DLZ_ROCKET: + Obj_DLZRocketThink(mobj); + break; case MT_DLZ_SEASAW_SPAWN: Obj_DLZSeasawThink(mobj); @@ -11165,12 +11169,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_RIDEROIDNODE: Obj_RideroidNodeSpawn(mobj); break; - case MT_DLZ_ROCKET: - Obj_DLZRocketSpawn(mobj); - break; case MT_DLZ_SEASAW_SPAWN: Obj_DLZSeasawSpawn(mobj); break; + case MT_DLZ_HOVER: + Obj_DLZHoverSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break; From 12b80b392bf1af0267865b0452035c868f29b7e0 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 11:26:56 +0200 Subject: [PATCH 15/39] hardcode ring vaccums --- src/info.c | 27 +++++++++++++++++ src/k_objects.h | 5 ++++ src/objects/dlzothers.c | 64 +++++++++++++++++++++++++++++++++++++++++ src/p_map.c | 8 ++++++ src/p_mobj.c | 7 +++++ 5 files changed, 111 insertions(+) diff --git a/src/info.c b/src/info.c index e17703b35..ef02b379b 100644 --- a/src/info.c +++ b/src/info.c @@ -30702,6 +30702,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SOLID, // flags S_NULL // raisestate }, + + { // MT_DLZ_SUCKEDRING, + -1, // doomednum + S_RING, // 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 + 0, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, }; diff --git a/src/k_objects.h b/src/k_objects.h index b76e64e4b..8d59ffeca 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -262,6 +262,11 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2); void Obj_DLZHoverSpawn(mobj_t *mo); void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2); +/* DLZ Ring Vaccum */ +void Obj_DLZRingVaccumSpawn(mobj_t *mo); +void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2); +void Obj_DLZSuckedRingThink(mobj_t *mo); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/dlzothers.c b/src/objects/dlzothers.c index 887813b60..482987218 100644 --- a/src/objects/dlzothers.c +++ b/src/objects/dlzothers.c @@ -32,6 +32,7 @@ void Obj_DLZHoverSpawn(mobj_t *mo) mo->destscale = mapobjectscale*4; } +// collision between MT_PLAYER and hover void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2) { player_t *p = mo->player; @@ -66,4 +67,67 @@ void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2) p->lasthover = leveltime; } +} + +// Ring Vaccum: +void Obj_DLZRingVaccumSpawn(mobj_t *mo) +{ + P_SetScale(mo, mapobjectscale*4); + mo->destscale = mapobjectscale*4; +} + +// collision between MT_FLINGRING and ring vaccum +void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2) +{ + mobj_t *fake; + + if (mo->z + mo->height < mo2->z) + return; + + if (mo->z > mo2->z + mo2->height) + return; + + if (!P_IsObjectOnGround(mo) || mo->momz) + return; + + fake = P_SpawnMobj(mo->x, mo->y, mo->z, MT_FLINGRING); + P_SetScale(fake, mo->scale); + fake->scalespeed = mapobjectscale/64; + fake->destscale = 1; + + P_SetTarget(&fake->target, mo2); + + fake->angle = R_PointToAngle2(mo2->x, mo2->y, fake->x, fake->y); + fake->movefactor = R_PointToDist2(mo2->x, mo2->y, fake->x, fake->y); + + P_RemoveMobj(mo); +} + +void Obj_DLZSuckedRingThink(mobj_t *mo) +{ + mobj_t *t = mo->target; + fixed_t x, y; + + // commit die if the target disappears for some fucking reason + if (!t || P_MobjWasRemoved(t)) + { + P_RemoveMobj(mo); + return; + } + + x = t->x + mo->movefactor*FINECOSINE(mo->angle>>ANGLETOFINESHIFT); + y = t->y + mo->movefactor*FINESINE(mo->angle>>ANGLETOFINESHIFT); + + P_MoveOrigin(mo, x, y, mo->z); + + if (mo->cusval < 24) + mo->cusval++; + + mo->angle += mo->cusval*ANG1; + + if (mo->cusval > 8 && mo->movefactor) + mo->movefactor -= 1; + + if (mo->scale < mapobjectscale/12) + P_RemoveMobj(mo); } \ No newline at end of file diff --git a/src/p_map.c b/src/p_map.c index 7adcefcde..cbf2c2a00 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -758,6 +758,14 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return BMIT_CONTINUE; } + if (thing->type == MT_DLZ_RINGVACCUM) + { + if (tm.thing->type == MT_FLINGRING) + Obj_DLZRingVaccumCollide(tm.thing, thing); + + return BMIT_CONTINUE; + } + if (tm.thing->type == MT_INSTAWHIP) { if (tm.thing->z > thing->z + thing->height) diff --git a/src/p_mobj.c b/src/p_mobj.c index f5566be6c..cd0e78087 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9733,6 +9733,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) Obj_DLZSeasawThink(mobj); break; + case MT_DLZ_SUCKEDRING: + Obj_DLZSuckedRingThink(mobj); + break; + default: // check mobj against possible water content, before movement code P_MobjCheckWater(mobj); @@ -11175,6 +11179,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_DLZ_HOVER: Obj_DLZHoverSpawn(mobj); break; + case MT_DLZ_RINGVACCUM: + Obj_DLZRingVaccumSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break; From fddc15f11f708cdd5d2704c8be517e3088168b10 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 11:32:59 +0200 Subject: [PATCH 16/39] Make sure to update seasaw reverse gravity flags --- src/objects/dlzseasaw.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index fe0e73dcd..1efc1334f 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -41,6 +41,13 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) mo->tracer->tics = 3; P_MoveOrigin(mo->tracer, mo->x, mo->y, mo->z); P_SetScale(mo->tracer, mo->scale); + + if (mo->eflags & MFE_VERTICALFLIP) + { + mo->tracer->eflags |= MFE_VERTICALFLIP; + mo->tracer->eflags |= MF2_OBJECTFLIP; + } + } @@ -63,6 +70,12 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) ptr->angle = visan; ptr->tics = 3; P_SetScale(ptr, mo->scale); + + if (mo->eflags & MFE_VERTICALFLIP) + { + ptr->eflags |= MFE_VERTICALFLIP; + ptr->flags2 |= MF2_OBJECTFLIP; + } if (ghostme && leveltime&1) { @@ -91,6 +104,13 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) P_SetOrigin(ptrp, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); // it's invisible so nobody cares about interpolating it. ptrp->angle = visan; ptrp->tics = 3; + + + if (mo->eflags & MFE_VERTICALFLIP) + { + ptrp->eflags |= MFE_VERTICALFLIP; + ptrp->flags2 |= MF2_OBJECTFLIP; + } hdist += 16; } From 058a1c03b5e791b775869cfdc3c44c3e20181d0f Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 12:48:52 +0200 Subject: [PATCH 17/39] Seasaw defs, variables + new function to sanitize checks for my hardcoded mess --- src/d_player.h | 5 ++ src/deh_tables.c | 12 ++++ src/info.c | 147 ++++++++++++++++++++++++++++++++++++++++ src/info.h | 18 +++++ src/k_kart.c | 12 ++++ src/k_kart.h | 3 + src/objects/bungee.c | 2 +- src/objects/dlzrocket.c | 2 +- src/objects/dlzseasaw.c | 4 ++ src/objects/rideroid.c | 3 +- src/p_saveg.c | 10 +++ src/p_setup.c | 6 +- 12 files changed, 218 insertions(+), 6 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 9101e3dc7..d08b12409 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -758,6 +758,11 @@ struct player_t INT32 seasawmoreangle; // used for reverse sesaws in DLZ. boolean seasawdir; // flips or not seasaw rotation + // water palace turbines (or cnz barrels, or whatever the hell people use it for nowadays) + tic_t turbine; // ticker (while true, we set the tracer to the turbine) + INT32 turbineangle; // angle around the turbine. ...Made in INT32 to make it easier to translate from lua + fixed_t turbineheight; // height around the turbine + boolean turbinespd; // if true, we used a sneaker and get the altpath. // diff --git a/src/deh_tables.c b/src/deh_tables.c index 52a11ea1c..3821b2f5c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4678,6 +4678,12 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DLZHOVER", "S_DLZROCKET_L", "S_DLZROCKET_R", + + "S_WPZFOUNTAIN", + "S_WPZFOUNTAINANIM", + "S_KURAGEN", + "S_KURAGENBOMB", + }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -5845,6 +5851,12 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DLZ_SEASAW_VISUAL", "MT_DLZ_RINGVACCUM", "MT_DLZ_SUCKEDRING", + + "MT_WATERPALACETURBINE", + "MT_WATERPALACEBUBBLE", + "MT_WATERPALACEFOUNTAIN", + "MT_KURAGEN", + "MT_KURAGENBOMB", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index ef02b379b..216cbcf62 100644 --- a/src/info.c +++ b/src/info.c @@ -907,6 +907,11 @@ char sprnames[NUMSPRITES + 1][5] = "DLZS", "DLZA", + // Water Palace Zone + "WPWL", // turbine + "WPZF", // fountain + "WPZK", // klagen + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5433,14 +5438,21 @@ state_t states[NUMSTATES] = {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK11}, // S_CHECKPOINT_SPARK10 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK1}, // S_CHECKPOINT_SPARK11 + // Las Vegas {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON + // Dead Line {SPR_DLZH, 0, -1, {NULL}, 0, 0, S_DLZHOVER}, // S_DLZHOVER {SPR_DLZR, 0, -1, {NULL}, 0, 0, S_DLZROCKET_L}, // S_DLZROCKET_L {SPR_DLZR, 1, -1, {NULL}, 0, 0, S_DLZROCKET_R}, // S_DLZROCKET_R + // Water Palace + {SPR_WPZF, 0, -1, {NULL}, 0, 0, S_WPZFOUNTAIN}, // S_WPZFOUNTAIN + {SPR_WPZF, 1|FF_ANIMATE, -1, {NULL}, 3, 2, S_WPZFOUNTAINANIM}, // S_WPZFOUNTAINANIM + {SPR_WPZK, FF_ANIMATE, -1, {NULL}, 3, 12, S_KURAGEN}, // S_KURAGEN + {SPR_WPZK, 4, -1, {NULL}, 0, 0, S_KURAGENBOMB}, // S_KURAGENBOMB }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -30730,6 +30742,141 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_WATERPALACETURBINE + 3400, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + + { // MT_WATERPALACEBUBBLE + -1, // doomednum + S_INVISIBLE, // 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 + 0, // speed + 32*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags + S_NULL // raisestate + }, + + { // MT_WATERPALACEFOUNTAIN + 3401, // doomednum + S_WPZFOUNTAIN, // 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 + 0, // speed + 16*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID, // flags + S_NULL // raisestate + }, + + { // MT_KURAGEN + 3402, // doomednum + S_KURAGEN, // 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 + 0, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + + { // MT_KURAGENBOMB + -1, // doomednum + S_KURAGENBOMB, // 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 + 0, // speed + 64*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 0, // mass + DMG_EXPLODE, // damage + sfx_None, // activesound + MF_PAIN, // flags + S_NULL // raisestate + }, + }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index 1db640ed3..d5ba39f76 100644 --- a/src/info.h +++ b/src/info.h @@ -1458,6 +1458,11 @@ typedef enum sprite SPR_DLZS, // DLZ Seasaw SPR_DLZA, // Helper arrows for rocket + SPR_WPWL, // turbine + SPR_WPZF, // fountain + SPR_WPZK, // klagen + + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -5866,6 +5871,13 @@ typedef enum state S_DLZROCKET_L, S_DLZROCKET_R, + // water palace zone + S_WPZFOUNTAIN, + S_WPZFOUNTAINANIM, + S_KURAGEN, + S_KURAGENBOMB, + + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -7052,6 +7064,12 @@ typedef enum mobj_type MT_DLZ_RINGVACCUM, MT_DLZ_SUCKEDRING, + MT_WATERPALACETURBINE, + MT_WATERPALACEBUBBLE, + MT_WATERPALACEFOUNTAIN, + MT_KURAGEN, + MT_KURAGENBOMB, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/k_kart.c b/src/k_kart.c index ccf30d4bd..01b895328 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -57,6 +57,18 @@ // comeback is Battle Mode's karma comeback, also bool // mapreset is set when enough players fill an empty server +// lat: used for when the player is in some weird state where it wouldn't be wise for it to be overwritten by another object that does similarly wacky shit. +boolean K_isPlayerInSpecialState(player_t *p) +{ + return ( + p->rideroid + || p->bungee + || p->dlzrocket + || p->seasaw + || p->turbine + ); +} + boolean K_IsDuelItem(mobjtype_t type) { switch (type) diff --git a/src/k_kart.h b/src/k_kart.h index e33580f81..1435430a9 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -228,6 +228,9 @@ UINT32 K_PointLimitForGametype(void); boolean K_Cooperative(void); +// lat: used for when the player is in some weird state where it wouldn't be wise for it to be overwritten by another object that does similarly wacky shit. +boolean K_isPlayerInSpecialState(player_t *p); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/bungee.c b/src/objects/bungee.c index 91f026545..1b5ae14cc 100644 --- a/src/objects/bungee.c +++ b/src/objects/bungee.c @@ -35,7 +35,7 @@ void Obj_BungeeSpecial(mobj_t *mo, player_t *p) mobj_t *latch; - if (p->bungee || P_IsObjectOnGround(p->mo) || p->springstars) + if (P_IsObjectOnGround(p->mo) || p->springstars || K_isPlayerInSpecialState(p)) return; P_InstaThrust(p->mo, 0, 0); diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index 153831d40..3dc1ba9b2 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -71,7 +71,7 @@ void Obj_DLZRocketDismount(player_t *p) // touching the rocket, initialize player vars etc... void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p) { - if (p->dlzrocket) // already on one, don't bother resetting, duh. + if (K_isPlayerInSpecialState(p)) // already on one, don't bother resetting, duh. return; p->mo->z = mo->z + 16*P_MobjFlip(p->mo)*mapobjectscale; diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 1efc1334f..17fc5e231 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -308,6 +308,10 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) // cooldown / respawning if (p->seasawcooldown || p->respawn.timer) return; + + // other wacko state that'd do very weird shit if we overwrote it. + if (K_isPlayerInSpecialState(p)) + return; // another player is already using the seasar if (mo2->target && !P_MobjWasRemoved(mo2->target) && mo2->target->target && !P_MobjWasRemoved(mo2->target->target)) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 768318a94..2b1f9eadc 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -510,7 +510,8 @@ void Obj_RideroidNodeThink(mobj_t *mo) // check for players coming near us. for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].rideroid || players[i].rdnodepull) + if (!playeringame[i] || players[i].spectator || players[i].rideroid || + players[i].rdnodepull || K_isPlayerInSpecialState(&players[i]) || P_PlayerInPain(&players[i])) continue; pmo = players[i].mo; diff --git a/src/p_saveg.c b/src/p_saveg.c index d9a6fc81b..f28981874 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -580,6 +580,11 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT32(save->p, players[i].seasawmoreangle); WRITEUINT8(save->p, players[i].seasawdir); + WRITEUINT32(save->p, players[i].turbine); + WRITEINT32(save->p, players[i].turbineangle); + WRITEFIXED(save->p, players[i].turbineheight); + WRITEUINT8(save->p, players[i].turbinespd); + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -1082,6 +1087,11 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].seasawmoreangle = READINT32(save->p); players[i].seasawdir = READUINT8(save->p); + players[i].turbine = READUINT32(save->p); + players[i].turbineangle = READINT32(save->p); + players[i].turbineheight = READFIXED(save->p); + players[i].turbinespd = READUINT8(save->p); + // respawnvars_t players[i].respawn.state = READUINT8(save->p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save->p); diff --git a/src/p_setup.c b/src/p_setup.c index da3f780b7..906310e33 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7263,7 +7263,7 @@ static void P_ConvertBinaryThingTypes(void) case 3786: // MT_BATTLEUFO_SPAWNER mapthings[i].thing_args[0] = mapthings[i].angle; break; - case 3400: // MT_WATERPALACETURBINE (TODO: not yet hardcoded) + case 3400: // MT_WATERPALACETURBINE { mtag_t tag = (mtag_t)mapthings[i].angle; INT32 j = Tag_FindLineSpecial(2009, tag); @@ -7312,8 +7312,8 @@ static void P_ConvertBinaryThingTypes(void) break; } - case 3441: // MT_DASHRING (TODO: not yet hardcoded) - case 3442: // MT_RAINBOWDASHRING (TODO: not yet hardcoded) + case 3441: // MT_DASHRING + case 3442: // MT_RAINBOWDASHRING mapthings[i].thing_args[0] = mapthings[i].options & 13; mapthings[i].thing_args[1] = mapthings[i].extrainfo; break; From df31c65ebbeed682126926e3abdcce63ba3455c4 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 16:32:32 +0200 Subject: [PATCH 18/39] Hardcode these godforsaken turbines --- src/k_kart.c | 9 +++++++++ src/k_objects.h | 6 ++++++ src/objects/CMakeLists.txt | 1 + src/p_mobj.c | 11 +++++++++++ 4 files changed, 27 insertions(+) diff --git a/src/k_kart.c b/src/k_kart.c index 01b895328..d869954b0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -62,6 +62,7 @@ boolean K_isPlayerInSpecialState(player_t *p) { return ( p->rideroid + || p->rdnodepull || p->bungee || p->dlzrocket || p->seasaw @@ -11863,6 +11864,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->seasawcooldown && !player->seasaw) player->seasawcooldown--; + + if (player->turbine) + { + if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer)) + Obj_playerWPZTurbine(player); + else + player->turbine--; // acts as a cooldown + } } void K_CheckSpectateStatus(boolean considermapreset) diff --git a/src/k_objects.h b/src/k_objects.h index 8d59ffeca..534e976c6 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -267,6 +267,12 @@ void Obj_DLZRingVaccumSpawn(mobj_t *mo); void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2); void Obj_DLZSuckedRingThink(mobj_t *mo); +/* WPZ Turbine */ +void Obj_WPZTurbineSpawn(mobj_t *mo); +void Obj_WPZTurbineThinker(mobj_t *mo); +void Obj_playerWPZTurbine(player_t *p); +void Obj_WPZBubbleThink(mobj_t *mo); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 042a39f90..e27538fd2 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -35,5 +35,6 @@ target_sources(SRB2SDL2 PRIVATE dlzrocket.c dlzseasaw.c dlzothers.c + wpzturbine.c shadow.cpp ) diff --git a/src/p_mobj.c b/src/p_mobj.c index cd0e78087..b41a9502e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9736,6 +9736,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_DLZ_SUCKEDRING: Obj_DLZSuckedRingThink(mobj); break; + + case MT_WATERPALACETURBINE: + Obj_WPZTurbineThinker(mobj); + break; + + case MT_WATERPALACEBUBBLE: + Obj_WPZBubbleThink(mobj); + break; default: // check mobj against possible water content, before movement code @@ -11182,6 +11190,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_DLZ_RINGVACCUM: Obj_DLZRingVaccumSpawn(mobj); break; + case MT_WATERPALACETURBINE: + Obj_WPZTurbineSpawn(mobj); + break; case MT_SNEAKERPANEL: Obj_SneakerPanelSpawn(mobj); break; From a710237fde8a6dc9cac9ab6c4bc57561da879e4b Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 23 Sep 2023 17:05:21 +0200 Subject: [PATCH 19/39] Hardcode the remainder of the WPZ objects --- src/k_objects.h | 7 + src/objects/CMakeLists.txt | 1 + src/objects/wpzothers.c | 97 ++++++++++ src/objects/wpzturbine.c | 385 +++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 12 ++ 5 files changed, 502 insertions(+) create mode 100644 src/objects/wpzothers.c create mode 100644 src/objects/wpzturbine.c diff --git a/src/k_objects.h b/src/k_objects.h index 534e976c6..cccdf8434 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -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 diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index e27538fd2..3561e3c1a 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -36,5 +36,6 @@ target_sources(SRB2SDL2 PRIVATE dlzseasaw.c dlzothers.c wpzturbine.c + wpzothers.c shadow.cpp ) diff --git a/src/objects/wpzothers.c b/src/objects/wpzothers.c new file mode 100644 index 000000000..56fa965a6 --- /dev/null +++ b/src/objects/wpzothers.c @@ -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); + } +} \ No newline at end of file diff --git a/src/objects/wpzturbine.c b/src/objects/wpzturbine.c new file mode 100644 index 000000000..daac89cc6 --- /dev/null +++ b/src/objects/wpzturbine.c @@ -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); +} \ No newline at end of file diff --git a/src/p_mobj.c b/src/p_mobj.c index b41a9502e..e66887d72 100644 --- a/src/p_mobj.c +++ b/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); From 32620fbb4fb06a3e53270c0862cff6275f4c72ba Mon Sep 17 00:00:00 2001 From: Lat Date: Sun, 24 Sep 2023 13:57:42 +0200 Subject: [PATCH 20/39] Fix these godforsaken rideroids --- src/d_player.h | 4 +- src/objects/rideroid.c | 96 ++++++++++++++++++++++++------------------ src/p_saveg.c | 8 ++-- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d08b12409..cc3fc9f9c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -725,9 +725,9 @@ struct player_t ////////////// boolean rideroid; // on rideroid y/n boolean rdnodepull; // being pulled by rideroid node. mo target is set to the node while this is true. - angle_t rideroidangle; // angle the rideroid is going at. This doesn't change once we're on it. + INT32 rideroidangle; // angle the rideroid is going at. This doesn't change once we're on it. INT32 because the code was originally written in lua and fuckshit happens with angle_t. fixed_t rideroidspeed; // speed the rideroid is to be moving at. - fixed_t rideroidrollangle; // rollangle while turning + INT32 rideroidrollangle; // rollangle while turning fixed_t rdaddmomx; // some speed variables to smoothe things out without fighting with the regular momentum system. fixed_t rdaddmomy; fixed_t rdaddmomz; diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 2b1f9eadc..06d39bb90 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -307,34 +307,34 @@ void Obj_RideroidThink(mobj_t *mo) // now actual movement: // first, do the movement for this frame - P_InstaThrust(pmo, mo->angle, p->rideroidspeed*mapobjectscale); + P_InstaThrust(pmo, (angle_t)p->rideroidangle, p->rideroidspeed*mapobjectscale); + basemomx = p->mo->momx; + basemomy = p->mo->momy; + 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->angle = (angle_t)p->rideroidangle; + p->drawangle = (angle_t)p->rideroidangle; + P_SetPlayerAngle(pmo->player, (angle_t)p->rideroidangle); 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; + SINT8 dir = 0; + INT32 a; if (p->cmd.turning < -400) { + a = (INT32)(mo->angle) - ANG1*90; P_Thrust(pmo, mo->angle - ANGLE_90, 2*mapobjectscale); p->rideroidrollangle -= ANG1*3; @@ -346,6 +346,7 @@ void Obj_RideroidThink(mobj_t *mo) } else if (p->cmd.turning > 400) { + a = (INT32)(mo->angle) + ANG1*90; P_Thrust(pmo, mo->angle + ANGLE_90, 2*mapobjectscale); p->rideroidrollangle += ANG1*3; @@ -360,38 +361,51 @@ void Obj_RideroidThink(mobj_t *mo) 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; - - if (mo->angle > ANGLE_90 && mo->angle < ANGLE_270) - P_Thrust(pmo, mo->angle - ANGLE_90, RIDEROIDMAXADD*6*mapobjectscale); - else - P_Thrust(pmo, mo->angle + ANGLE_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)); + if (dir != 0) + { + + // save the added momentum + p->rdaddmomx = pmo->momx - basemomx; + p->rdaddmomy = pmo->momy - basemomy; - // now cancel it. - pmo->momx = savemomx; - pmo->momy = savemomy; - //CONS_Printf("NEWCURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale); - + CONS_Printf("AX1: %d, AY1: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale); + + pmo->momx = basemomx; + 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; + + a = (INT32)(mo->angle) - dir*ANG1*90; + P_Thrust(pmo, (angle_t)a, RIDEROIDMAXADD*3*mapobjectscale); + + xthreshold = pmo->momx - basemomx; + ythreshold = pmo->momy - basemomy; + + //CONS_Printf("XT: %d (%d), YT: %d (%d)\n", xthreshold/mapobjectscale, abs(xthreshold/mapobjectscale), ythreshold/mapobjectscale, abs(ythreshold/mapobjectscale)); + + // clamp the momentums using the calculated thresholds. + + // the fixedmul check checks if both numbers are of the same sign. + if (abs(p->rdaddmomx) > abs(xthreshold)) + p->rdaddmomx = xthreshold; + + if (abs(p->rdaddmomy) > abs(ythreshold)) + p->rdaddmomy = ythreshold; + + //CONS_Printf("AX2: %d, AY2: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale); + + // now cancel it. + pmo->momx = savemomx; + pmo->momy = savemomy; + //CONS_Printf("NEWCURR: %d, %d\n", pmo->momx/mapobjectscale, pmo->momy/mapobjectscale); + } } else // not turning { diff --git a/src/p_saveg.c b/src/p_saveg.c index f28981874..3effdb84f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -556,9 +556,9 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].rideroid); WRITEUINT8(save->p, players[i].rdnodepull); - WRITEANGLE(save->p, players[i].rideroidangle); + WRITEINT32(save->p, players[i].rideroidangle); WRITEFIXED(save->p, players[i].rideroidspeed); - WRITEANGLE(save->p, players[i].rideroidrollangle); + WRITEINT32(save->p, players[i].rideroidrollangle); WRITEFIXED(save->p, players[i].rdaddmomx); WRITEFIXED(save->p, players[i].rdaddmomy); WRITEFIXED(save->p, players[i].rdaddmomz); @@ -1063,9 +1063,9 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].rideroid = READUINT8(save->p); players[i].rdnodepull = READUINT8(save->p); - players[i].rideroidangle = READANGLE(save->p); + players[i].rideroidangle = READINT32(save->p); players[i].rideroidspeed = READFIXED(save->p); - players[i].rideroidrollangle = READANGLE(save->p); + players[i].rideroidrollangle = READINT32(save->p); players[i].rdaddmomx = READFIXED(save->p); players[i].rdaddmomy = READFIXED(save->p); players[i].rdaddmomz = READFIXED(save->p); From 3be4156e59aaedb8672f18a49d9812052c54dbf2 Mon Sep 17 00:00:00 2001 From: Lat Date: Sun, 24 Sep 2023 14:21:49 +0200 Subject: [PATCH 21/39] Make rideroid speed up to 150% speed with first blood --- src/objects/rideroid.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 06d39bb90..cbed41efa 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -24,9 +24,10 @@ #include "../k_waypoint.h" #include "../k_respawn.h" #include "../k_collide.h" +#include "../k_color.h" #define NODERADIUS 260 -#define NODEPULLOK 16 +#define NODEPULLOK 48 #define NODEROTSPEED ANG1 #define RIDEROIDSPEED 80 @@ -160,8 +161,13 @@ static void Obj_rideroidTrail(mobj_t *mo) P_SetScale(t, max(1, mapobjectscale*5/6 - ((10-j)*mapobjectscale/120))); t->destscale = 1; - if (p && p != &players[consoleplayer] && j) - t->renderflags |= RF_DONTDRAW; + if (p) + { + if (p != &players[consoleplayer] && j) + t->renderflags |= RF_DONTDRAW; + else if (p->startboost) + t->color = K_RainbowColor(leveltime); + } } } @@ -250,7 +256,7 @@ void Obj_RideroidThink(mobj_t *mo) // 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. + maxspd = (maxspd*12)/10; // Ring Boost: 120% max speed. if (p->draftpower) { @@ -258,6 +264,9 @@ void Obj_RideroidThink(mobj_t *mo) maxspd += (draftperc/5) / 100; } + if (p->startboost) + maxspd = (maxspd*15)/10; // 150% speed + // increase speed as we go unless we're turning harshly. if (p->rideroidspeed*mapobjectscale < maxspd) { @@ -368,7 +377,7 @@ void Obj_RideroidThink(mobj_t *mo) p->rdaddmomx = pmo->momx - basemomx; p->rdaddmomy = pmo->momy - basemomy; - CONS_Printf("AX1: %d, AY1: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale); + //CONS_Printf("AX1: %d, AY1: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale); pmo->momx = basemomx; pmo->momy = basemomy; From b1c1b658da6dcf473878c86cf9dbd6de7772e08c Mon Sep 17 00:00:00 2001 From: Lat Date: Sun, 24 Sep 2023 14:29:44 +0200 Subject: [PATCH 22/39] Speed up DLZ rockets with first blood --- src/objects/dlzrocket.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index 3dc1ba9b2..3c1e26cde 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -24,6 +24,7 @@ #include "../k_waypoint.h" #include "../k_respawn.h" #include "../k_collide.h" +#include "../k_color.h" #define DLZROCKETDIST 96 #define DLZROCKETSPEED 80 @@ -112,6 +113,9 @@ void Obj_playerDLZRocket(player_t *p) if (p->ringboost) maxspd += 10; + if (p->startboost) + maxspd += 30; + // set player speed if (p->dlzrocketspd < maxspd) p->dlzrocketspd++; @@ -184,6 +188,10 @@ void Obj_playerDLZRocket(player_t *p) expl->color = p->mo->color; P_SetScale(expl, mapobjectscale); expl->destscale = 2*mapobjectscale; + + if (p->startboost) + expl->color = K_RainbowColor(leveltime); + } visangle += ANGLE_180; From 0aa6d8c86bc633b866ec264d27b876cd2e4b1f92 Mon Sep 17 00:00:00 2001 From: Lat Date: Sun, 24 Sep 2023 17:08:59 +0200 Subject: [PATCH 23/39] Fix missing bubbles on underwater WPZ turbines --- src/objects/wpzturbine.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/objects/wpzturbine.c b/src/objects/wpzturbine.c index daac89cc6..4e80b10f0 100644 --- a/src/objects/wpzturbine.c +++ b/src/objects/wpzturbine.c @@ -94,7 +94,7 @@ static void Obj_WPZTurbineUpdate(mobj_t *mo) } // bubbles if we're underwater - if (mo->eflags & MFE_UNDERWATER && leveltime%(TICRATE/2) == 0) + if (mo->z < mo->watertop && leveltime%10 == 0) { INT32 dradius = TURBINE_SPIN; @@ -106,7 +106,7 @@ static void Obj_WPZTurbineUpdate(mobj_t *mo) if (mt->thing_args[7]) dradius = mt->thing_args[7]; - bubbleradius = P_RandomRange(PR_FUZZ, dradius/4, dradius); + bubbleradius = P_RandomRange(PR_FUZZ, dradius/4, (dradius*3)/2); bubbleang = P_RandomRange(PR_FUZZ, 0, 359)*ANG1; bx = mo->x + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT)); @@ -357,13 +357,13 @@ void Obj_WPZBubbleThink(mobj_t *mo) return; } - mt = mo->spawnpoint; + mt = t->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)); + tx = t->x + FixedMul(mapobjectscale, mo->movecount*FINECOSINE(ang>>ANGLETOFINESHIFT)); + ty = t->y + FixedMul(mapobjectscale, mo->movecount*FINESINE(ang>>ANGLETOFINESHIFT)); mo->momx = (tx - mo->x)/24; mo->momy = (ty - mo->y)/24; @@ -382,4 +382,7 @@ void Obj_WPZBubbleThink(mobj_t *mo) } mo->angle += 3*ANG1 * (mt->thing_args[0] ? -1 : 1); + + if (mo->z > mo->watertop || mo->z > mo->ceilingz) + P_RemoveMobj(mo); } \ No newline at end of file From 08ee7dabac0faf7eec242ba03a5dfcc6ab3c1876 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 25 Sep 2023 10:39:02 +0200 Subject: [PATCH 24/39] Fix Klagen spawn height --- src/objects/wpzothers.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/objects/wpzothers.c b/src/objects/wpzothers.c index 56fa965a6..2652b0bce 100644 --- a/src/objects/wpzothers.c +++ b/src/objects/wpzothers.c @@ -40,9 +40,16 @@ void Obj_WPZFountainThink(mobj_t *mo) // kuragens void Obj_WPZKuragenThink(mobj_t *mo) { + //(void)mo; boolean active = false; - P_SetScale(mo, mapobjectscale*2); + // .....and i need to do this... because? + if (!mo->cusval) + { + P_SetScale(mo, mapobjectscale*2); + mo->destscale = mapobjectscale*2; + mo->cusval = 1; + } if (!(mo->spawnpoint->options & 1 || mo->spawnpoint->thing_args[0])) // extra flag skips player checks, making it a decoration. { From 8d3cf30eec09007c392d36495689d495cf8cae02 Mon Sep 17 00:00:00 2001 From: Lat Date: Mon, 25 Sep 2023 11:04:45 +0200 Subject: [PATCH 25/39] expose player variables to lua --- src/lua_playerlib.c | 127 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index dca270903..9b81cfc9a 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -463,6 +463,69 @@ static int player_get(lua_State *L) else if (fastcmp(field,"follower")) LUA_PushUserdata(L, plr->follower, META_MOBJ); // + + // rideroids + else if (fastcmp(field,"rideroid")) + lua_pushboolean(L, plr->rideroid); + else if (fastcmp(field,"rdnodepull")) + lua_pushboolean(L, plr->rdnodepull); + else if (fastcmp(field,"rideroidangle")) + lua_pushinteger(L, plr->rideroidangle); + else if (fastcmp(field,"rideroidspeed")) + lua_pushinteger(L, plr->rideroidspeed); + else if (fastcmp(field,"rideroidrollangle")) + lua_pushinteger(L, plr->rideroidrollangle); + else if (fastcmp(field,"rdaddmomx")) + lua_pushinteger(L, plr->rdaddmomx); + else if (fastcmp(field,"rdaddmomy")) + lua_pushinteger(L, plr->rdaddmomy); + else if (fastcmp(field,"rdaddmomz")) + lua_pushinteger(L, plr->rdaddmomz); + + // bungee + else if (fastcmp(field,"bungee")) + lua_pushinteger(L, plr->bungee); + + // dlz hover + else if (fastcmp(field,"lasthover")) + lua_pushinteger(L, plr->lasthover); + + // dlz rocket + else if (fastcmp(field,"dlzrocket")) + lua_pushinteger(L, plr->dlzrocket); + else if (fastcmp(field,"dlzrocketangle")) + lua_pushinteger(L, plr->dlzrocketangle); + else if (fastcmp(field,"dlzrocketanglev")) + lua_pushinteger(L, plr->dlzrocketanglev); + else if (fastcmp(field,"dlzrocketspd")) + lua_pushinteger(L, plr->dlzrocketspd); + + // seasaws + else if (fastcmp(field,"seasaw")) + lua_pushboolean(L, plr->seasaw); + else if (fastcmp(field,"seasawcooldown")) + lua_pushinteger(L, plr->seasawcooldown); + else if (fastcmp(field,"seasawdist")) + lua_pushinteger(L, plr->seasawdist); + else if (fastcmp(field,"seasawangle")) + lua_pushinteger(L, plr->seasawangle); + else if (fastcmp(field,"seasawangleadd")) + lua_pushinteger(L, plr->seasawangleadd); + else if (fastcmp(field,"seasawmoreangle")) + lua_pushinteger(L, plr->seasawmoreangle); + else if (fastcmp(field,"seasawdir")) + lua_pushboolean(L, plr->seasawdir); + + // turbine + else if (fastcmp(field,"turbine")) + lua_pushinteger(L, plr->turbine); + else if (fastcmp(field,"turbineangle")) + lua_pushinteger(L, plr->turbineangle); + else if (fastcmp(field,"turbineheight")) + lua_pushinteger(L, plr->turbineheight); + else if (fastcmp(field,"turbinespd")) + lua_pushinteger(L, plr->turbinespd); + else if (fastcmp(field,"charflags")) lua_pushinteger(L, plr->charflags); else if (fastcmp(field,"followitem")) @@ -857,6 +920,70 @@ static int player_set(lua_State *L) plr->followerready = luaL_checkboolean(L, 3); else if (fastcmp(field,"follower")) // it's probably best we don't allow the follower mobj to change. return NOSET; + + // time to add to the endless elseif list!!!! + // rideroids + else if (fastcmp(field,"rideroid")) + plr->rideroid = luaL_checkboolean(L, 3); + else if (fastcmp(field,"rdnodepull")) + plr->rdnodepull = luaL_checkboolean(L, 3); + else if (fastcmp(field,"rideroidangle")) + plr->rideroidangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rideroidspeed")) + plr->rideroidspeed = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rideroidrollangle")) + plr->rideroidrollangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rdaddmomx")) + plr->rdaddmomx = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rdaddmomy")) + plr->rdaddmomy = luaL_checkinteger(L, 3); + else if (fastcmp(field,"rdaddmomz")) + plr->rdaddmomz = luaL_checkinteger(L, 3); + + // bungee + else if (fastcmp(field,"bungee")) + plr->bungee = luaL_checkinteger(L, 3); + + // dlz hover + else if (fastcmp(field,"lasthover")) + plr->lasthover = luaL_checkinteger(L, 3); + + // dlz rocket + else if (fastcmp(field,"dlzrocket")) + plr->dlzrocket = luaL_checkinteger(L, 3); + else if (fastcmp(field,"dlzrocketangle")) + plr->dlzrocketangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"dlzrocketanglev")) + plr->dlzrocketanglev = luaL_checkinteger(L, 3); + else if (fastcmp(field,"dlzrocketspd")) + plr->dlzrocketspd = luaL_checkinteger(L, 3); + + // seasaws + else if (fastcmp(field,"seasaw")) + plr->seasaw = luaL_checkboolean(L, 3); + else if (fastcmp(field,"seasawcooldown")) + plr->seasawcooldown = luaL_checkinteger(L, 3); + else if (fastcmp(field,"seasawdist")) + plr->seasawdist = luaL_checkinteger(L, 3); + else if (fastcmp(field,"seasawangle")) + plr->seasawangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"seasawangleadd")) + plr->seasawangleadd = luaL_checkinteger(L, 3); + else if (fastcmp(field,"seasawmoreangle")) + plr->seasawmoreangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"seasawdir")) + plr->seasawdir = luaL_checkboolean(L, 3); + + // turbines + else if (fastcmp(field,"turbine")) + plr->turbine = luaL_checkinteger(L, 3); + else if (fastcmp(field,"turbineangle")) + plr->turbineangle = luaL_checkinteger(L, 3); + else if (fastcmp(field,"turbineheight")) + plr->turbineheight = luaL_checkinteger(L, 3); + else if (fastcmp(field,"turbinespd")) + plr->turbinespd = luaL_checkinteger(L, 3); + // else if (fastcmp(field,"charflags")) plr->charflags = (UINT32)luaL_checkinteger(L, 3); From 490959b6f7d45df98b58412574732bf7388e34de Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:04:14 +0100 Subject: [PATCH 26/39] Newly added object files: Fix trailing whitespace + EOF newline --- src/objects/bungee.c | 38 +++---- src/objects/dlzothers.c | 38 +++---- src/objects/dlzrocket.c | 71 +++++++------ src/objects/dlzseasaw.c | 124 +++++++++++------------ src/objects/eggball.c | 34 +++---- src/objects/rideroid.c | 212 +++++++++++++++++++-------------------- src/objects/wpzothers.c | 18 ++-- src/objects/wpzturbine.c | 124 +++++++++++------------ 8 files changed, 328 insertions(+), 331 deletions(-) diff --git a/src/objects/bungee.c b/src/objects/bungee.c index 1b5ae14cc..a5f9519aa 100644 --- a/src/objects/bungee.c +++ b/src/objects/bungee.c @@ -32,17 +32,17 @@ // Touching the bungee, used in p_inter.c void Obj_BungeeSpecial(mobj_t *mo, player_t *p) { - + mobj_t *latch; - + if (P_IsObjectOnGround(p->mo) || p->springstars || K_isPlayerInSpecialState(p)) return; - + P_InstaThrust(p->mo, 0, 0); p->bungee = BUNGEE_LATCH; p->mo->flags |= MF_NOCLIPTHING; // prevent players from bumping if they latch onto the same bungee. p->pflags |= PF_NOFASTFALL; // didn't know this flag existed but it's very convenient!! - + latch = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_THOK); P_SetMobjState(latch, S_INVISIBLE); latch->angle = mo->angle; @@ -54,22 +54,22 @@ void Obj_BungeeSpecial(mobj_t *mo, player_t *p) // this is the thinker to call on the player when they get bungee'd. void Obj_playerBungeeThink(player_t *p) { - + mobj_t *bungee = p->mo->tracer; UINT8 i; - - // someone removed it + + // someone removed it if (!bungee || P_MobjWasRemoved(bungee)) return; - + bungee->tics = 4; // we set this to a low value so that it despawns if the player vanishes for some reason. - + if (p->bungee == BUNGEE_LATCH) { // rr has super high gravity which gets in the way. p->mo->flags |= MF_NOGRAVITY; p->mo->momz = (p->mo->momz*9)/10; - + if (abs(p->mo->momz) < 6*mapobjectscale) { p->bungee = BUNGEE_LAUNCH; @@ -80,40 +80,40 @@ void Obj_playerBungeeThink(player_t *p) else if (p->bungee == BUNGEE_LAUNCH) { p->mo->momz = (p->mo->momz*12)/10; - + // if we go above/below (depending on our flip flags) the bungee, release us! if ((p->mo->eflags & MFE_VERTICALFLIP && p->mo->z < bungee->z) || (!(p->mo->eflags & MFE_VERTICALFLIP) && p->mo->z > bungee->z )) { - + p->mo->flags &= ~MF_NOGRAVITY; p->mo->flags &= ~MF_NOCLIPTHING; p->pflags &= ~PF_NOFASTFALL; p->bungee = BUNGEE_NONE; P_InstaThrust(p->mo, bungee->angle, p->mo->momz/8); p->mo->momz = (p->mo->momz*3)/4; - + p->springstars = TICRATE; // these are used as a buffer not to latch to vines again. p->springcolor = SKINCOLOR_EMERALD; - + P_RemoveMobj(bungee); - P_SetTarget(&p->mo->tracer, NULL); + P_SetTarget(&p->mo->tracer, NULL); return; } } - + // basic visuals (but hey they work fine enough!) for (i=0; i<8; i++) { fixed_t xpos = -(bungee->x - p->mo->x) /8 *i; fixed_t ypos = -(bungee->y - p->mo->y) /8 *i; fixed_t zpos = -(bungee->z - p->mo->z) /8 *i; - + mobj_t *seg = P_SpawnMobj(bungee->x + xpos, bungee->y + ypos, bungee->z + zpos, MT_THOK); - + P_SetScale(seg, mapobjectscale/3); seg->color = SKINCOLOR_EMERALD; seg->frame = 0; seg->fuse = 2; } -} \ No newline at end of file +} diff --git a/src/objects/dlzothers.c b/src/objects/dlzothers.c index 482987218..90c5ab331 100644 --- a/src/objects/dlzothers.c +++ b/src/objects/dlzothers.c @@ -36,10 +36,10 @@ void Obj_DLZHoverSpawn(mobj_t *mo) void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2) { player_t *p = mo->player; - + if (!p || p->lasthover == leveltime) return; - + if (abs(mo->z - mo2->z) < 512*mapobjectscale) { // momz adjust @@ -57,14 +57,14 @@ void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2) mo->momz += 8*mapobjectscale; } } - + // speed adjust if (p->speed > K_GetKartSpeed(p, false, false)) P_Thrust(mo, R_PointToAngle2(0, 0, -mo->momx, -mo->momy), mapobjectscale/16); - + if (!S_SoundPlaying(mo, sfx_s3kc6s)) S_StartSound(mo, sfx_s3kc6s); - + p->lasthover = leveltime; } } @@ -83,23 +83,23 @@ void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2) if (mo->z + mo->height < mo2->z) return; - + if (mo->z > mo2->z + mo2->height) return; - + if (!P_IsObjectOnGround(mo) || mo->momz) return; - + fake = P_SpawnMobj(mo->x, mo->y, mo->z, MT_FLINGRING); P_SetScale(fake, mo->scale); fake->scalespeed = mapobjectscale/64; fake->destscale = 1; - + P_SetTarget(&fake->target, mo2); - + fake->angle = R_PointToAngle2(mo2->x, mo2->y, fake->x, fake->y); fake->movefactor = R_PointToDist2(mo2->x, mo2->y, fake->x, fake->y); - + P_RemoveMobj(mo); } @@ -107,27 +107,27 @@ void Obj_DLZSuckedRingThink(mobj_t *mo) { mobj_t *t = mo->target; fixed_t x, y; - + // commit die if the target disappears for some fucking reason if (!t || P_MobjWasRemoved(t)) { P_RemoveMobj(mo); return; } - + x = t->x + mo->movefactor*FINECOSINE(mo->angle>>ANGLETOFINESHIFT); y = t->y + mo->movefactor*FINESINE(mo->angle>>ANGLETOFINESHIFT); - + P_MoveOrigin(mo, x, y, mo->z); - + if (mo->cusval < 24) mo->cusval++; - + mo->angle += mo->cusval*ANG1; - + if (mo->cusval > 8 && mo->movefactor) mo->movefactor -= 1; - + if (mo->scale < mapobjectscale/12) P_RemoveMobj(mo); -} \ No newline at end of file +} diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index 3c1e26cde..160e221f2 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -36,25 +36,25 @@ void Obj_DLZRocketThink(mobj_t *mo) { UINT8 i; angle_t an = mo->angle + ANGLE_90; - + if (mo->extravalue1) return; - + for (i = 0; i < 2; i++) { fixed_t x = mo->x + FixedMul(mapobjectscale, DLZROCKETDIST*FINECOSINE(an>>ANGLETOFINESHIFT)); fixed_t y = mo->y + FixedMul(mapobjectscale, DLZROCKETDIST*FINESINE(an>>ANGLETOFINESHIFT)); - + mobj_t *r = P_SpawnMobj(x, y, mo->z, MT_THOK); P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R); P_SetScale(r, (mapobjectscale*3)/2); r->destscale = (mapobjectscale*3)/2; r->angle = mo->spawnpoint->angle*ANG1; r->tics = -1; - + an += ANGLE_180; } - + mo->extravalue1 = 1; } @@ -63,7 +63,7 @@ void Obj_DLZRocketDismount(player_t *p) // we aren't mounted on one. if (!p->dlzrocket) return; - + p->dlzrocket = 0; K_SpawnMineExplosion(p->mo, p->mo->color, 3); S_StartSound(p->mo, sfx_s3k4e); @@ -74,29 +74,29 @@ void Obj_DLZRocketSpecial(mobj_t *mo, player_t *p) { if (K_isPlayerInSpecialState(p)) // already on one, don't bother resetting, duh. return; - + p->mo->z = mo->z + 16*P_MobjFlip(p->mo)*mapobjectscale; P_SetPlayerAngle(p->mo->player, mo->angle); p->dlzrocket = true; p->dlzrocketangle = mo->angle; p->dlzrocketanglev = 0; p->dlzrocketspd = DLZROCKETSPEED; - + p->spinouttimer = 0; p->wipeoutslow = 0; - + S_StartSound(mo, sfx_s262); } void Obj_playerDLZRocket(player_t *p) { - + fixed_t maxspd = DLZROCKETSPEED; angle_t visangle; UINT8 i, j; - + p->dlzrocket++; - + // helper arrows at the start of the ride to tell players they can move freely if (p->dlzrocket < TICRATE*2 && leveltime%10 < 5) @@ -107,22 +107,20 @@ void Obj_playerDLZRocket(player_t *p) P_SetScale(arr, 2*mapobjectscale); arr->tics = 2; } - - + // calc max speed if (p->ringboost) maxspd += 10; - + if (p->startboost) maxspd += 30; - + // set player speed if (p->dlzrocketspd < maxspd) p->dlzrocketspd++; else if (p->dlzrocketspd > maxspd) p->dlzrocket--; - - + // so long as PF_STASIS is applied, let the angle be overwritten freely. // this is used by seasaws but can be used for misc modding purposes too. if (p->pflags & PF_STASIS) @@ -131,42 +129,42 @@ void Obj_playerDLZRocket(player_t *p) { SINT8 turndir = 0; P_SetPlayerAngle(p->mo->player, p->dlzrocketangle); - + if (p->cmd.turning > 0) turndir = 1; else if (p->cmd.turning < 0) turndir = -1; - + p->dlzrocketangle += turndir*DLZROCKETTURNSPEED; - + if (p->cmd.throwdir > 0) p->dlzrocketanglev = min(DLZROCKETMAXVERT, p->dlzrocketanglev + DLZROCKETVERTSPEED); else if (p->cmd.throwdir < 0) p->dlzrocketanglev = max(-DLZROCKETMAXVERT, p->dlzrocketanglev - DLZROCKETVERTSPEED); - + } - + // angle correction on ceilings (THIS CODE LOOKS AWFUL AND IT CAN PROBABLY BE DONE BETTER......) if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && (p->mo->z+p->mo->height >= p->mo->ceilingz)) || (p->mo->eflags & MFE_VERTICALFLIP && p->mo->z <= p->mo->floorz)) if ( (!(p->mo->eflags & MFE_VERTICALFLIP) && p->dlzrocketanglev > 0) || (p->mo->eflags & MFE_VERTICALFLIP && p->dlzrocketanglev < 0)) p->dlzrocketanglev = 0; - - + + if (!(p->pflags & PF_STASIS)) { angle_t van = p->dlzrocketanglev /4; P_InstaThrust(p->mo, p->dlzrocketangle, FixedMul(mapobjectscale, p->dlzrocketspd*FINECOSINE(van>>ANGLETOFINESHIFT))); - p->mo->momz = FixedMul(mapobjectscale, p->dlzrocketspd*FINESINE((angle_t)p->dlzrocketanglev>>ANGLETOFINESHIFT)); + p->mo->momz = FixedMul(mapobjectscale, p->dlzrocketspd*FINESINE((angle_t)p->dlzrocketanglev>>ANGLETOFINESHIFT)); } - + if (leveltime%4 == 0) S_StartSound(p->mo, sfx_s1c8); - + // finally, visuals. visangle = p->mo->angle + ANGLE_90; - + for (i = 0; i < 2; i++) { fixed_t x = p->mo->x + FixedMul(mapobjectscale, 56*FINECOSINE(visangle>>ANGLETOFINESHIFT)); @@ -176,29 +174,28 @@ void Obj_playerDLZRocket(player_t *p) P_SetMobjState(r, i ? S_DLZROCKET_L : S_DLZROCKET_R); P_SetScale(r, (mapobjectscale*3)/2); r->angle = p->mo->angle; - + for (j = 0; j < 2; j++) { fixed_t xoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; fixed_t yoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; fixed_t soffs = P_RandomRange(PR_FUZZ, 0, 3); - + mobj_t *expl = P_SpawnMobj(r->x + xoffs, r->y + yoffs, r->z + xoffs, MT_THOK); P_SetMobjState(expl, S_QUICKBOOM1+soffs); expl->color = p->mo->color; P_SetScale(expl, mapobjectscale); expl->destscale = 2*mapobjectscale; - + if (p->startboost) expl->color = K_RainbowColor(leveltime); - - + + } visangle += ANGLE_180; } - + if ((p->dlzrocket > 10 && (P_IsObjectOnGround(p->mo) || p->mo->eflags & MFE_JUSTBOUNCEDWALL)) || p->spinouttimer || p->wipeoutslow || p->tumbleHeight) Obj_DLZRocketDismount(p); - -} \ No newline at end of file +} diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 17fc5e231..36c7756aa 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -28,34 +28,34 @@ // updates the seasaw's visuals and hitboxes using the hnext/hprev list. static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) { - + mobj_t *ptr = mo; mobj_t *ptrp = mo; UINT8 i, j; angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90; P_SetScale(mo, 2*mapobjectscale); - + if (mo->tracer && !P_MobjWasRemoved(mo->tracer)) { mo->tracer->tics = 3; P_MoveOrigin(mo->tracer, mo->x, mo->y, mo->z); P_SetScale(mo->tracer, mo->scale); - + if (mo->eflags & MFE_VERTICALFLIP) { mo->tracer->eflags |= MFE_VERTICALFLIP; mo->tracer->eflags |= MF2_OBJECTFLIP; } - + } - - + + for (i = 0; i < 2; i++) { INT32 dist = 32; // visuals dist INT32 hdist = 16; // hitbox dist - + // visuals for (j = 0; j < 2; j++) { @@ -65,7 +65,7 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) fixed_t x = mo->x + FixedMul(mo->scale, dist*FINECOSINE(visan>>ANGLETOFINESHIFT)); fixed_t y = mo->y + FixedMul(mo->scale, dist*FINESINE(visan>>ANGLETOFINESHIFT)); ptr = ptr->hnext; - + P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); ptr->angle = visan; ptr->tics = 3; @@ -76,7 +76,7 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) ptr->eflags |= MFE_VERTICALFLIP; ptr->flags2 |= MF2_OBJECTFLIP; } - + if (ghostme && leveltime&1) { mobj_t *g = P_SpawnGhostMobj(ptr); @@ -84,23 +84,23 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) g->color = mo->color; g->fuse = 3; } - + dist += 55; } } - + // hitboxes: for (j = 0; j < 8; j++) { // get our mobj. if (ptrp && !P_MobjWasRemoved(ptrp) && ptrp->hprev && !P_MobjWasRemoved(ptrp->hprev)) { - + fixed_t x = mo->x + FixedMul(mo->scale, hdist*FINECOSINE(visan>>ANGLETOFINESHIFT)); - fixed_t y = mo->y + FixedMul(mo->scale, hdist*FINESINE(visan>>ANGLETOFINESHIFT)); - + fixed_t y = mo->y + FixedMul(mo->scale, hdist*FINESINE(visan>>ANGLETOFINESHIFT)); + ptrp = ptrp->hprev; - + P_SetOrigin(ptrp, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); // it's invisible so nobody cares about interpolating it. ptrp->angle = visan; ptrp->tics = 3; @@ -111,12 +111,12 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) ptrp->eflags |= MFE_VERTICALFLIP; ptrp->flags2 |= MF2_OBJECTFLIP; } - + hdist += 16; } - + } - + visan += ANGLE_180; } } @@ -128,10 +128,10 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) mobj_t *ptr = mo; mobj_t *ptrp = mo; UINT8 i, j; - + // setup vars mo->extravalue1 = (INT32)mo->angle; - + // center pole: pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); pole->tics = -1; @@ -139,37 +139,37 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) pole->frame = 0; P_SetTarget(&pole->target, mo); P_SetTarget(&mo->tracer, pole); - + if (mo->eflags & MFE_VERTICALFLIP) pole->eflags |= MFE_VERTICALFLIP; - + // spawn visuals / hitboxes. for (i = 0; i < 2; i++) // for each side... { for (j = 0; j < 2; j++) // spawn the 2 visual papersprites on each side. { // right now we don't care if the objects are positionned properly. - + mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_VISUAL); vis->sprite = SPR_DLZS; vis->frame = (j+1)|FF_PAPERSPRITE; vis->tics = -1; - + if (mo->eflags & MFE_VERTICALFLIP) { vis->eflags |= MFE_VERTICALFLIP; vis->flags2 |= MF2_OBJECTFLIP; } - + P_SetTarget(&vis->target, mo); P_SetTarget(&ptr->hnext, vis); // save in an hnext list for updating later. ptr = vis; } - + for (j = 0; j < 8; j++) // spawn the 8 hitboxes on each side. { // right now we don't care if the objects are positionned properly. - + mobj_t *h = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_DLZ_SEASAW_HITBOX); h->extravalue1 = i; // keep track of which side we're on. h->tics = -1; @@ -179,22 +179,22 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) h->eflags |= MFE_VERTICALFLIP; h->flags2 |= MF2_OBJECTFLIP; } - + P_SetTarget(&h->target, mo); P_SetTarget(&ptrp->hprev, h); // save in an hprev list for updating later. ptrp = h; } } - + // update after spawning the objects so that they appear in the right spot when the map loads. - Obj_DLZSeasawUpdate(mo, false); + Obj_DLZSeasawUpdate(mo, false); } static void Obj_DLZSeasawReset(mobj_t *mo) { mo->extravalue1 = (INT32)mo->angle; P_SetTarget(&mo->target, NULL); - Obj_DLZSeasawUpdate(mo, false); + Obj_DLZSeasawUpdate(mo, false); } // main seasaw thinker. @@ -203,26 +203,26 @@ void Obj_DLZSeasawThink(mobj_t *mo) boolean ghost = false; SINT8 rot = 1; fixed_t px, py; - + if (mo->target && !P_MobjWasRemoved(mo->target)) { mobj_t *t = mo->target; player_t *p = t->player; // our target should always be a player, do NOT porceed if it isn't. - + if (!p) // untarget this instantly. { Obj_DLZSeasawReset(mo); return; } - + if (!mo->extravalue2) rot = -1; - + // first half of the animation... if (!p->seasawdir) { INT32 angleadd = ANG1*max(4, (mo->movefactor/3)/mapobjectscale) * rot; - + if (p->seasawangleadd > 175) angleadd /= max(1, (p->seasawangleadd - 160)/8); @@ -242,39 +242,39 @@ void Obj_DLZSeasawThink(mobj_t *mo) p->seasawangleadd = 0; // reset, we're gonna do a full 360! p->seasawmoreangle = p->seasawangleadd - 170; S_StartSound(t, sfx_s3k88); - S_StartSound(t, sfx_s3ka2); + S_StartSound(t, sfx_s3ka2); } } else { INT32 angleadd = (mo->cvmem*2 +1)*(-rot); mo->cvmem++; - + p->seasawangleadd += abs(angleadd)/2; // for some reason i need to do this and i'm actually not sure why. mo->extravalue1 += angleadd*ANG1; p->seasawangle += angleadd*ANG1; - - P_SetPlayerAngle(p, (angle_t)(p->seasawangle - ANGLE_90*rot)); + + P_SetPlayerAngle(p, (angle_t)(p->seasawangle - ANGLE_90*rot)); ghost = true; - + if (p->seasawangleadd >= 340 + p->seasawmoreangle) { // reset everything and send the player zooming Obj_DLZSeasawReset(mo); - + P_SetPlayerAngle(p, mo->angle); P_MoveOrigin(t, t->x, t->y, t->z); // miscall that to set the position properly. P_InstaThrust(t, mo->angle, mo->movefactor*3); // send the player flying at triple the speed they came at us with. S_StartSound(t, sfx_cdfm62); - + p->seasawangleadd = 0; p->seasawangle = 0; p->seasawmoreangle = 0; p->seasaw = false; - - Obj_DLZSeasawUpdate(mo, true); + + Obj_DLZSeasawUpdate(mo, true); return; - + } } // update the player @@ -285,9 +285,9 @@ void Obj_DLZSeasawThink(mobj_t *mo) } else Obj_DLZSeasawReset(mo); - + // finally, update the visuals. - Obj_DLZSeasawUpdate(mo, ghost); + Obj_DLZSeasawUpdate(mo, ghost); } // ported just for convenience of not needing to rewrite the code to account for UINT32 angles... @@ -308,7 +308,7 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) // cooldown / respawning if (p->seasawcooldown || p->respawn.timer) return; - + // other wacko state that'd do very weird shit if we overwrote it. if (K_isPlayerInSpecialState(p)) return; @@ -316,23 +316,23 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) // another player is already using the seasar if (mo2->target && !P_MobjWasRemoved(mo2->target) && mo2->target->target && !P_MobjWasRemoved(mo2->target->target)) return; - + // height checks if (mo->z + mo->height < mo2->z) return; - + if (mo->z > mo2->z + mo2->height) return; - + // too slow. if (p->speed < K_GetKartSpeed(p, false, false)/3) return; - - + + momangle = angtoint(R_PointToAngle2(0, 0, mo->momx, mo->momy)); - + //CONS_Printf("%d / %d -> %d\n", momangle, angtoint(mo2->target->angle), (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180))); - + // this depends on the side we hit the thing from. if (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180) > 60) { @@ -340,17 +340,17 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) mo2->target->extravalue1 += ANGLE_180; invert = true; } - + mo2->target->movefactor = p->speed; // keep the speed the player was going at. mo2->target->extravalue2 = mo2->extravalue1; // which side of the pole are we on? - + // if inverted, then invert the value too. if (invert) mo2->target->extravalue2 = (!mo2->target->extravalue2) ? 1 : 0; - + P_SetTarget(&mo2->target->target, mo); mo2->target->cvmem = 0; - + // set player vars now: p->seasawdist = R_PointToDist2(mo->x, mo->y, mo2->target->x, mo2->target->y) /FRACUNIT; // distance from us to the center p->seasawangle = (INT32)R_PointToAngle2(mo2->target->x, mo2->target->y, mo->x, mo->y); // angle from the center to us @@ -359,6 +359,6 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) p->seasaw = true; p->pflags |= PF_STASIS; p->seasawcooldown = TICRATE/2; - + S_StartSound(mo, sfx_s3k88); -} \ No newline at end of file +} diff --git a/src/objects/eggball.c b/src/objects/eggball.c index 0d9f684f5..1fa9653bd 100644 --- a/src/objects/eggball.c +++ b/src/objects/eggball.c @@ -37,7 +37,7 @@ void Obj_EggBallSpawnerThink(mobj_t *mo) mobj_t *ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_LSZ_EGGBALL); ball->angle = mo->angle; P_SetScale(ball, 6*mapobjectscale); - + mo->extravalue1 = P_RandomRange(PR_FUZZ, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); } mo->extravalue1--; @@ -50,18 +50,18 @@ void Obj_EggBallSpawnerThink(mobj_t *mo) void Obj_EggBallThink(mobj_t *mo) { - + P_SetScale(mo, 6*mapobjectscale); - + if (mo->eflags & MFE_JUSTHITFLOOR && mo->threshold) { if (mo->threshold < -10*mapobjectscale) { UINT8 i; - + mo->momz = (fixed_t)(-mo->threshold)/8; - + for (i=0; i<16; i++) { angle_t an = ANG1; @@ -70,14 +70,14 @@ void Obj_EggBallThink(mobj_t *mo) P_InstaThrust(dust, (360/16)*an*i, mapobjectscale*24); // the angle thing is to avoid a warning due to overflows. dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; } - + S_StartSound(mo, sfx_s3k59); - + P_StartQuakeFromMobj(FRACUNIT*20, 6, 512 * mapobjectscale, mo); - + } } - + if (!mo->extravalue1) { if (P_IsObjectOnGround(mo)) @@ -95,17 +95,17 @@ void Obj_EggBallThink(mobj_t *mo) fixed_t dx = mo->x + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momx*2; fixed_t dy = mo->y + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momy*2; fixed_t dz = mo->z; - + mobj_t *dust = P_SpawnMobj(dx, dy, dz, MT_DRIFTDUST); P_SetScale(dust, mapobjectscale*3); - dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; dust->destscale = mapobjectscale*8; } - + P_InstaThrust(mo, mo->angle, mo->cusval); mo->extravalue2 += 1; mo->frame = mo->extravalue2 % (24 * 2) / 2; // 24 is for frame Y. - + // build up speed if (P_IsObjectOnGround(mo)) { @@ -124,11 +124,11 @@ void Obj_EggBallThink(mobj_t *mo) } } } - - mo->movedir = mo->z; + + mo->movedir = mo->z; } mo->threshold = mo->momz; - + if (P_CheckDeathPitCollide(mo)) P_RemoveMobj(mo); -} \ No newline at end of file +} diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index cbed41efa..58258d14b 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -48,17 +48,17 @@ static void plr_resetRideroidVars(player_t *p) p->rideroidangle = 0; p->rideroidspeed = 0; p->rideroidrollangle = 0; - + p->rdaddmomx = 0; p->rdaddmomy = 0; - p->rdaddmomz = 0; + p->rdaddmomz = 0; } // kills the rideroid and removes it from the map. static void Obj_killRideroid(mobj_t *mo) { UINT8 i; - + for (i = 0; i < 32; i++) { mobj_t *t = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); @@ -76,11 +76,11 @@ static void Obj_killRideroid(mobj_t *mo) void Obj_getPlayerOffRideroid(mobj_t *mo) { mobj_t *pmo = mo->target; - + if (pmo && !P_MobjWasRemoved(pmo)) { player_t *p = pmo->player; - + pmo->flags &= ~MF_NOGRAVITY; plr_resetRideroidVars(p); @@ -89,9 +89,9 @@ void Obj_getPlayerOffRideroid(mobj_t *mo) mo->momy = mo->momy*2; mo->momz = 0; mo->target = NULL; - + S_StartSound(mo, sfx_ridr4); - + } } @@ -103,11 +103,11 @@ static void Obj_explodeRideroid(mobj_t *mo) Obj_getPlayerOffRideroid(mo); K_SpawnMineExplosion(pmo, pmo->color, 3); - S_StartSound(pmo, sfx_s3k4e); + S_StartSound(pmo, sfx_s3k4e); Obj_killRideroid(mo); - + // @TODO: quake. - + } // used to create a smooth trail. @@ -120,23 +120,23 @@ static void Obj_rideroidTrail(mobj_t *mo) { mobj_t *pmo = mo->target; player_t *p = NULL; - + UINT8 i, j; - + angle_t h_an = mo->angle + ANG1*90; - + if (pmo && !P_MobjWasRemoved(pmo)) { p = pmo->player; // used to make some graphics local to save on framerate mo->color = pmo->color; mo->colorized = pmo->colorized; - } + } // from here, we will use the following: // extravalue1: prev x // extravalue2: prev y // cusval: prev z // cvmem: prev roll angle - + for (j = 0; j < 9; j++) { for (i = 0; i < 2; i++) @@ -146,14 +146,14 @@ static void Obj_rideroidTrail(mobj_t *mo) 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; @@ -168,10 +168,10 @@ static void Obj_rideroidTrail(mobj_t *mo) else if (p->startboost) t->color = K_RainbowColor(leveltime); } - + } } - + mo->extravalue1 = (INT32)mo->x; mo->extravalue2 = (INT32)mo->y; mo->cusval = (INT32)mo->z; @@ -182,15 +182,15 @@ static void Obj_rideroidTrail(mobj_t *mo) 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); mo->momx = pmo->momx; mo->momy = pmo->momy; mo->momz = pmo->momz; - + Obj_rideroidTrail(mo); } @@ -199,16 +199,16 @@ 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)) { if (!mo->fuse) @@ -226,69 +226,69 @@ void Obj_RideroidThink(mobj_t *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 = (maxspd*12)/10; // Ring Boost: 120% max speed. - + if (p->draftpower) { UINT8 draftperc = (p->draftpower*100 / FRACUNIT); // 0-100% maxspd += (draftperc/5) / 100; } - + if (p->startboost) maxspd = (maxspd*15)/10; // 150% speed - + // 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. + 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 @@ -304,22 +304,22 @@ void Obj_RideroidThink(mobj_t *mo) 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, (angle_t)p->rideroidangle, p->rideroidspeed*mapobjectscale); basemomx = p->mo->momx; basemomy = p->mo->momy; - + pmo->momx += p->rdaddmomx; pmo->momy += p->rdaddmomy; pmo->momz += p->rdaddmomz; @@ -329,7 +329,7 @@ void Obj_RideroidThink(mobj_t *mo) 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); @@ -340,71 +340,71 @@ void Obj_RideroidThink(mobj_t *mo) fixed_t savemomy = pmo->momy; SINT8 dir = 0; INT32 a; - + if (p->cmd.turning < -400) { a = (INT32)(mo->angle) - ANG1*90; P_Thrust(pmo, mo->angle - ANGLE_90, 2*mapobjectscale); p->rideroidrollangle -= ANG1*3; - + if (p->rideroidrollangle < -ANG1*25) p->rideroidrollangle = -ANG1*25; - + dir = 1; - + } else if (p->cmd.turning > 400) { a = (INT32)(mo->angle) + ANG1*90; P_Thrust(pmo, mo->angle + ANGLE_90, 2*mapobjectscale); p->rideroidrollangle += ANG1*3; - + if (p->rideroidrollangle > ANG1*25) p->rideroidrollangle = ANG1*25; - - dir = -1; + + dir = -1; } - + if (dir != 0 && leveltime & 1 && p->rideroidspeed > RIDEROIDSPEED/2) { p->rideroidspeed -= 1; } - + if (dir != 0) { - + // save the added momentum p->rdaddmomx = pmo->momx - basemomx; p->rdaddmomy = pmo->momy - basemomy; //CONS_Printf("AX1: %d, AY1: %d\n", p->rdaddmomx/mapobjectscale, p->rdaddmomy/mapobjectscale); - + pmo->momx = basemomx; 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; - + a = (INT32)(mo->angle) - dir*ANG1*90; P_Thrust(pmo, (angle_t)a, RIDEROIDMAXADD*3*mapobjectscale); - + xthreshold = pmo->momx - basemomx; ythreshold = pmo->momy - basemomy; - + //CONS_Printf("XT: %d (%d), YT: %d (%d)\n", xthreshold/mapobjectscale, abs(xthreshold/mapobjectscale), ythreshold/mapobjectscale, abs(ythreshold/mapobjectscale)); - + // clamp the momentums using the calculated thresholds. - + // the fixedmul check checks if both numbers are of the same sign. if (abs(p->rdaddmomx) > abs(xthreshold)) p->rdaddmomx = xthreshold; - + if (abs(p->rdaddmomy) > abs(ythreshold)) p->rdaddmomy = ythreshold; @@ -423,39 +423,39 @@ void Obj_RideroidThink(mobj_t *mo) 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; + p->rideroidspeed -= 1; } else p->rdaddmomz = (p->rdaddmomz*6)/10; - + } // transposed lua code. @@ -470,25 +470,25 @@ void Obj_RideroidNodeSpawn(mobj_t *mo) 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; fixed_t zpos = mo->z + 64*mapobjectscale + mapobjectscale*96*i; - + ang *= ANG1; // this has to be done here or the warning prevents the compile, we don't care about overflowing here. - + 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; @@ -496,15 +496,15 @@ void Obj_RideroidNodeSpawn(mobj_t *mo) 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; - } + } } } @@ -514,57 +514,57 @@ void Obj_RideroidNodeThink(mobj_t *mo) 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 || K_isPlayerInSpecialState(&players[i]) || P_PlayerInPain(&players[i])) 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; - + 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"); - + } } } diff --git a/src/objects/wpzothers.c b/src/objects/wpzothers.c index 2652b0bce..3132e4b04 100644 --- a/src/objects/wpzothers.c +++ b/src/objects/wpzothers.c @@ -42,7 +42,7 @@ void Obj_WPZKuragenThink(mobj_t *mo) { //(void)mo; boolean active = false; - + // .....and i need to do this... because? if (!mo->cusval) { @@ -50,7 +50,7 @@ void Obj_WPZKuragenThink(mobj_t *mo) mo->destscale = mapobjectscale*2; mo->cusval = 1; } - + if (!(mo->spawnpoint->options & 1 || mo->spawnpoint->thing_args[0])) // extra flag skips player checks, making it a decoration. { UINT8 i; @@ -58,13 +58,13 @@ void Obj_WPZKuragenThink(mobj_t *mo) { 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; @@ -72,11 +72,11 @@ void Obj_WPZKuragenThink(mobj_t *mo) } } } - + if (active && mo->extravalue1) { mo->extravalue1--; - + if (!mo->extravalue1) { mobj_t *b = P_SpawnMobj(mo->x, mo->y, mo->z, MT_KURAGENBOMB); @@ -98,7 +98,7 @@ void Obj_WPZKuragenBombThink(mobj_t *mo) P_SetScale(mo, mapobjectscale/2); P_RadiusAttack(mo, mo, FRACUNIT*192, DMG_EXPLODE, false); A_MineExplode(mo); - + P_RemoveMobj(mo); } -} \ No newline at end of file +} diff --git a/src/objects/wpzturbine.c b/src/objects/wpzturbine.c index 4e80b10f0..b75a3bd2d 100644 --- a/src/objects/wpzturbine.c +++ b/src/objects/wpzturbine.c @@ -40,16 +40,16 @@ 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; } @@ -60,22 +60,22 @@ 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)); - + 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)) { @@ -88,15 +88,15 @@ static void Obj_WPZTurbineUpdate(mobj_t *mo) ptr->destscale = mapobjectscale*4; ptr->angle = ang; } - + ang += (360/8)*ANG1; } } - - // bubbles if we're underwater + + // bubbles if we're underwater if (mo->z < mo->watertop && leveltime%10 == 0) { - + INT32 dradius = TURBINE_SPIN; INT32 bubbleradius; angle_t bubbleang; @@ -105,14 +105,14 @@ static void Obj_WPZTurbineUpdate(mobj_t *mo) if (mt->thing_args[7]) dradius = mt->thing_args[7]; - + bubbleradius = P_RandomRange(PR_FUZZ, dradius/4, (dradius*3)/2); 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; @@ -135,44 +135,44 @@ void Obj_WPZTurbineThinker(mobj_t *mo) 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; } } @@ -198,46 +198,46 @@ void Obj_playerWPZTurbine(player_t *p) 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) @@ -255,13 +255,13 @@ void Obj_playerWPZTurbine(player_t *p) 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) @@ -276,9 +276,9 @@ void Obj_playerWPZTurbine(player_t *p) 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)); @@ -288,7 +288,7 @@ void Obj_playerWPZTurbine(player_t *p) 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; @@ -297,22 +297,22 @@ void Obj_playerWPZTurbine(player_t *p) 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 @@ -320,25 +320,25 @@ void Obj_playerWPZTurbine(player_t *p) 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 @@ -348,7 +348,7 @@ void Obj_WPZBubbleThink(mobj_t *mo) mobj_t *t = mo->tracer; fixed_t tx, ty; mapthing_t *mt; - + // where // where did it go if (!t || P_MobjWasRemoved(t)) @@ -356,18 +356,18 @@ void Obj_WPZBubbleThink(mobj_t *mo) P_RemoveMobj(mo); return; } - + mt = t->spawnpoint; if (!mt) return; - + mo->momz = mapobjectscale*16; tx = t->x + FixedMul(mapobjectscale, mo->movecount*FINECOSINE(ang>>ANGLETOFINESHIFT)); ty = t->y + FixedMul(mapobjectscale, mo->movecount*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; @@ -380,9 +380,9 @@ void Obj_WPZBubbleThink(mobj_t *mo) bubl->frame = 0; bubl->tics = TICRATE; } - + mo->angle += 3*ANG1 * (mt->thing_args[0] ? -1 : 1); - + if (mo->z > mo->watertop || mo->z > mo->ceilingz) P_RemoveMobj(mo); -} \ No newline at end of file +} From d3e6c6ab0244ecb045a0e11589e6b40f1cad828d Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:10:43 +0100 Subject: [PATCH 27/39] Newly added object files: Fix Random classes - Was previously abusing PR_FUZZ - Add PR_TRACKHAZARD, for randomised track hazards --- src/m_random.h | 1 + src/objects/dlzrocket.c | 6 +++--- src/objects/eggball.c | 10 +++++----- src/objects/rideroid.c | 6 +++--- src/objects/wpzturbine.c | 16 ++++++++-------- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/m_random.h b/src/m_random.h index 18579596d..479ea24ef 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -73,6 +73,7 @@ typedef enum PR_SPARKLE, // Endsign and/or Emerald PR_MOVINGTARGET, // Randomised moving targets + PR_TRACKHAZARD, // Randomised track hazards PR_BATTLEUFO, // Battle UFO spawning diff --git a/src/objects/dlzrocket.c b/src/objects/dlzrocket.c index 160e221f2..dc5325713 100644 --- a/src/objects/dlzrocket.c +++ b/src/objects/dlzrocket.c @@ -177,9 +177,9 @@ void Obj_playerDLZRocket(player_t *p) for (j = 0; j < 2; j++) { - fixed_t xoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; - fixed_t yoffs = P_RandomRange(PR_FUZZ, -6, 6)*mapobjectscale; - fixed_t soffs = P_RandomRange(PR_FUZZ, 0, 3); + fixed_t xoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale; + fixed_t yoffs = P_RandomRange(PR_EXPLOSION, -6, 6)*mapobjectscale; + fixed_t soffs = P_RandomRange(PR_EXPLOSION, 0, 3); mobj_t *expl = P_SpawnMobj(r->x + xoffs, r->y + yoffs, r->z + xoffs, MT_THOK); P_SetMobjState(expl, S_QUICKBOOM1+soffs); diff --git a/src/objects/eggball.c b/src/objects/eggball.c index 1fa9653bd..4a74e3647 100644 --- a/src/objects/eggball.c +++ b/src/objects/eggball.c @@ -38,7 +38,7 @@ void Obj_EggBallSpawnerThink(mobj_t *mo) ball->angle = mo->angle; P_SetScale(ball, 6*mapobjectscale); - mo->extravalue1 = P_RandomRange(PR_FUZZ, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); + mo->extravalue1 = P_RandomRange(PR_TRACKHAZARD, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); } mo->extravalue1--; } @@ -68,7 +68,7 @@ void Obj_EggBallThink(mobj_t *mo) mobj_t *dust = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DRIFTDUST); P_SetScale(dust, mapobjectscale*3); P_InstaThrust(dust, (360/16)*an*i, mapobjectscale*24); // the angle thing is to avoid a warning due to overflows. - dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + dust->momz = P_RandomRange(PR_DECORATION, 0, 7)*mapobjectscale; } S_StartSound(mo, sfx_s3k59); @@ -92,13 +92,13 @@ void Obj_EggBallThink(mobj_t *mo) { if (P_IsObjectOnGround(mo) && mo->extravalue2 &1) { - fixed_t dx = mo->x + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momx*2; - fixed_t dy = mo->y + P_RandomRange(PR_FUZZ, -96, 96)*mapobjectscale - mo->momy*2; + fixed_t dx = mo->x + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momx*2; + fixed_t dy = mo->y + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momy*2; fixed_t dz = mo->z; mobj_t *dust = P_SpawnMobj(dx, dy, dz, MT_DRIFTDUST); P_SetScale(dust, mapobjectscale*3); - dust->momz = P_RandomRange(PR_FUZZ, 0, 7)*mapobjectscale; + dust->momz = P_RandomRange(PR_DECORATION, 0, 7)*mapobjectscale; dust->destscale = mapobjectscale*8; } diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 58258d14b..1a4415ce3 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -65,9 +65,9 @@ static void Obj_killRideroid(mobj_t *mo) t->color = SKINCOLOR_TEAL; t->frame = FF_FULLBRIGHT; t->destscale = 1; - t->momx = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; - t->momy = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; - t->momz = P_RandomRange(PR_DECORATION, -32, 32)*mapobjectscale; + t->momx = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale; + t->momy = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale; + t->momz = P_RandomRange(PR_EXPLOSION, -32, 32)*mapobjectscale; } P_RemoveMobj(mo); } diff --git a/src/objects/wpzturbine.c b/src/objects/wpzturbine.c index b75a3bd2d..7ce18bfd4 100644 --- a/src/objects/wpzturbine.c +++ b/src/objects/wpzturbine.c @@ -106,8 +106,8 @@ static void Obj_WPZTurbineUpdate(mobj_t *mo) if (mt->thing_args[7]) dradius = mt->thing_args[7]; - bubbleradius = P_RandomRange(PR_FUZZ, dradius/4, (dradius*3)/2); - bubbleang = P_RandomRange(PR_FUZZ, 0, 359)*ANG1; + bubbleradius = P_RandomRange(PR_BUBBLE, dradius/4, (dradius*3)/2); + bubbleang = P_RandomRange(PR_BUBBLE, 0, 359)*ANG1; bx = mo->x + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT)); by = mo->y + FixedMul(mapobjectscale, bubbleradius*FINECOSINE(bubbleang>>ANGLETOFINESHIFT)); @@ -285,9 +285,9 @@ void Obj_playerWPZTurbine(player_t *p) 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; + fixed_t rx = pmo->x + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; + fixed_t ry = pmo->y + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; + fixed_t rz = pmo->z + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK); P_SetScale(bubl, pmo->scale*2); @@ -370,9 +370,9 @@ void Obj_WPZBubbleThink(mobj_t *mo) 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; + fixed_t rx = mo->x + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; + fixed_t ry = mo->y + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; + fixed_t rz = mo->z + P_RandomRange(PR_DECORATION, -64, 64)*mapobjectscale; mobj_t *bubl = P_SpawnMobj(rx, ry, rz, MT_THOK); P_SetScale(bubl, mapobjectscale*4); bubl->destscale = 1; From 4f980dc949f7ba5710d78d6d7d949825b405e316 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:14:05 +0100 Subject: [PATCH 28/39] Obj_rideroidTrail: Use (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag) instead of consoleplayer hack --- src/objects/rideroid.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 1a4415ce3..7aee8a53a 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -163,9 +163,10 @@ static void Obj_rideroidTrail(mobj_t *mo) if (p) { - if (p != &players[consoleplayer] && j) - t->renderflags |= RF_DONTDRAW; - else if (p->startboost) + if (j) + t->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(p)); + + if (p->startboost) t->color = K_RainbowColor(leveltime); } From c17b2a44b349321333e1c46780a5aae9838a3dd7 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:17:52 +0100 Subject: [PATCH 29/39] Obj_getPlayerOffRideroid: NULL check --- src/objects/rideroid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 7aee8a53a..64ed0cc5c 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -82,7 +82,9 @@ void Obj_getPlayerOffRideroid(mobj_t *mo) player_t *p = pmo->player; pmo->flags &= ~MF_NOGRAVITY; - plr_resetRideroidVars(p); + + if (p) + plr_resetRideroidVars(p); mo->fuse = TICRATE/2; mo->momx = mo->momx*2; From a68a0b0135c41fca2261ca5e0df91032015f5d6e Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:51:58 +0100 Subject: [PATCH 30/39] All other modified files: Trailing whitespace cleanup --- src/d_player.h | 14 +++++++------- src/deh_tables.c | 14 +++++++------- src/info.c | 38 ++++++++++++++++++------------------- src/info.h | 34 ++++++++++++++++----------------- src/k_kart.c | 12 ++++++------ src/lua_playerlib.c | 46 ++++++++++++++++++++++----------------------- src/p_inter.c | 6 +++--- src/p_map.c | 18 +++++++++--------- src/p_mobj.c | 26 ++++++++++++------------- src/p_saveg.c | 24 +++++++++++------------ 10 files changed, 116 insertions(+), 116 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 05c6de2d3..89161e23c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -722,7 +722,7 @@ struct player_t tic_t spheredigestion; SINT8 glanceDir; // Direction the player is trying to look backwards in - + ////////////// // rideroid // ////////////// @@ -734,24 +734,24 @@ struct player_t fixed_t rdaddmomx; // some speed variables to smoothe things out without fighting with the regular momentum system. fixed_t rdaddmomy; fixed_t rdaddmomz; - + //////////// // bungee // //////////// UINT8 bungee; // constants are defined with the object file for the bungee. - + //////////////////// // dead line zone // //////////////////// // hovers tic_t lasthover; // used for the hover mobjs - + // rockets tic_t dlzrocket; // counts up as we stay on a rocket. angle_t dlzrocketangle; // current travel angle with the rocket. INT32 dlzrocketanglev; // current vertical travel angle with the rocket. signed instead of angle_t. fixed_t dlzrocketspd; // current rocket travel speed. - + // seasaws (variables are shared with other seasaw-like objects) boolean seasaw; // true if using a seasaw tic_t seasawcooldown; // cooldown to avoid triggering the same seasaw over and over @@ -760,13 +760,13 @@ struct player_t INT32 seasawangleadd; // used to spin the seasaw INT32 seasawmoreangle; // used for reverse sesaws in DLZ. boolean seasawdir; // flips or not seasaw rotation - + // water palace turbines (or cnz barrels, or whatever the hell people use it for nowadays) tic_t turbine; // ticker (while true, we set the tracer to the turbine) INT32 turbineangle; // angle around the turbine. ...Made in INT32 to make it easier to translate from lua fixed_t turbineheight; // height around the turbine boolean turbinespd; // if true, we used a sneaker and get the altpath. - + // SINT8 lives; diff --git a/src/deh_tables.c b/src/deh_tables.c index 3821b2f5c..ea7049d8d 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4671,7 +4671,7 @@ 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", @@ -4683,7 +4683,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_WPZFOUNTAINANIM", "S_KURAGEN", "S_KURAGENBOMB", - + }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -5836,14 +5836,14 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_CHECKPOINT_END", "MT_SCRIPT_THING", - + "MT_RIDEROID", "MT_RIDEROIDNODE", - + "MT_LSZ_BUNGEE", "MT_LSZ_EGGBALLSPAWNER", "MT_LSZ_EGGBALL", - + "MT_DLZ_HOVER", "MT_DLZ_ROCKET", "MT_DLZ_SEASAW_SPAWN", @@ -5851,12 +5851,12 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DLZ_SEASAW_VISUAL", "MT_DLZ_RINGVACCUM", "MT_DLZ_SUCKEDRING", - + "MT_WATERPALACETURBINE", "MT_WATERPALACEBUBBLE", "MT_WATERPALACEFOUNTAIN", "MT_KURAGEN", - "MT_KURAGENBOMB", + "MT_KURAGENBOMB", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 216cbcf62..897fdcb2a 100644 --- a/src/info.c +++ b/src/info.c @@ -891,27 +891,27 @@ char sprnames[NUMSPRITES + 1][5] = "CPT1", // Checkpoint Orb "CPT2", // Checkpoint Stick "CPT3", // Checkpoint Base - + // rideroid (see info.h for detail) "RDRD", "RDRA", "RDRC", "RDRL", - + // leaf storm egg ball. "LSZB", - + // Dead Line Zone "DLZH", "DLZR", "DLZS", - "DLZA", - + "DLZA", + // Water Palace Zone "WPWL", // turbine "WPZF", // fountain - "WPZK", // klagen - + "WPZK", // klagen + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5437,17 +5437,17 @@ state_t states[NUMSTATES] = {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK10}, // S_CHECKPOINT_SPARK9 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK11}, // S_CHECKPOINT_SPARK10 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_CHECKPOINT_SPARK1}, // S_CHECKPOINT_SPARK11 - + // Las Vegas {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON - + // Dead Line {SPR_DLZH, 0, -1, {NULL}, 0, 0, S_DLZHOVER}, // S_DLZHOVER - + {SPR_DLZR, 0, -1, {NULL}, 0, 0, S_DLZROCKET_L}, // S_DLZROCKET_L {SPR_DLZR, 1, -1, {NULL}, 0, 0, S_DLZROCKET_R}, // S_DLZROCKET_R - + // Water Palace {SPR_WPZF, 0, -1, {NULL}, 0, 0, S_WPZFOUNTAIN}, // S_WPZFOUNTAIN {SPR_WPZF, 1|FF_ANIMATE, -1, {NULL}, 3, 2, S_WPZFOUNTAINANIM}, // S_WPZFOUNTAINANIM @@ -30741,7 +30741,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY, // flags S_NULL // raisestate }, - + { // MT_WATERPALACETURBINE 3400, // doomednum S_INVISIBLE, // spawnstate @@ -30767,8 +30767,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // activesound MF_NOGRAVITY|MF_NOBLOCKMAP, // flags S_NULL // raisestate - }, - + }, + { // MT_WATERPALACEBUBBLE -1, // doomednum S_INVISIBLE, // spawnstate @@ -30794,7 +30794,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // activesound MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP, // flags S_NULL // raisestate - }, + }, { // MT_WATERPALACEFOUNTAIN 3401, // doomednum @@ -30822,7 +30822,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SOLID, // flags S_NULL // raisestate }, - + { // MT_KURAGEN 3402, // doomednum S_KURAGEN, // spawnstate @@ -30848,7 +30848,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // activesound MF_NOGRAVITY, // flags S_NULL // raisestate - }, + }, { // MT_KURAGENBOMB -1, // doomednum @@ -30875,8 +30875,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // activesound MF_PAIN, // flags S_NULL // raisestate - }, - + }, + }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index d5ba39f76..ec40722be 100644 --- a/src/info.h +++ b/src/info.h @@ -1241,7 +1241,7 @@ typedef enum sprite SPR_ARK3, SPR_ARK4, SPR_ARK5, - + SPR_BUMP, // Player/shell bump SPR_FLEN, // Shell hit graphics stuff @@ -1445,24 +1445,24 @@ typedef enum sprite SPR_CPT1, // Checkpoint Orb SPR_CPT2, // Checkpoint Stick SPR_CPT3, // Checkpoint Base - + SPR_RDRD, // rideroid SPR_RDRA, // rideroid node sprites SPR_RDRC, SPR_RDRL, - + SPR_LSZB, // eggman ball. - + SPR_DLZH, // DLZ Hover SPR_DLZR, // DLZ Rocket SPR_DLZS, // DLZ Seasaw SPR_DLZA, // Helper arrows for rocket - + SPR_WPWL, // turbine SPR_WPZF, // fountain SPR_WPZK, // klagen - - + + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -5861,23 +5861,23 @@ typedef enum state S_CHECKPOINT_SPARK9, S_CHECKPOINT_SPARK10, S_CHECKPOINT_SPARK11, - + // rideroid S_RIDEROID, S_RIDEROID_ICON, - + // dead line zone S_DLZHOVER, S_DLZROCKET_L, S_DLZROCKET_R, - + // water palace zone S_WPZFOUNTAIN, S_WPZFOUNTAINANIM, S_KURAGEN, S_KURAGENBOMB, - - + + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -7048,14 +7048,14 @@ typedef enum mobj_type MT_CHECKPOINT_END, MT_SCRIPT_THING, - + MT_RIDEROID, MT_RIDEROIDNODE, - + MT_LSZ_BUNGEE, MT_LSZ_EGGBALLSPAWNER, MT_LSZ_EGGBALL, - + MT_DLZ_HOVER, MT_DLZ_ROCKET, MT_DLZ_SEASAW_SPAWN, @@ -7063,13 +7063,13 @@ typedef enum mobj_type MT_DLZ_SEASAW_VISUAL, MT_DLZ_RINGVACCUM, MT_DLZ_SUCKEDRING, - + MT_WATERPALACETURBINE, MT_WATERPALACEBUBBLE, MT_WATERPALACEFOUNTAIN, MT_KURAGEN, MT_KURAGENBOMB, - + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/k_kart.c b/src/k_kart.c index fff639b47..d5ec96971 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8268,7 +8268,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->incontrol = 0; player->incontrol++; } - + player->incontrol = min(player->incontrol, 5*TICRATE); player->incontrol = max(player->incontrol, -5*TICRATE); @@ -11871,18 +11871,18 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->pflags &= ~PF_AIRFAILSAFE; } - + Obj_RingShooterInput(player); - + if (player->bungee) Obj_playerBungeeThink(player); - + if (player->dlzrocket) Obj_playerDLZRocket(player); - + if (player->seasawcooldown && !player->seasaw) player->seasawcooldown--; - + if (player->turbine) { if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer)) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 869e481e3..f7794197f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -465,36 +465,36 @@ static int player_get(lua_State *L) else if (fastcmp(field,"follower")) LUA_PushUserdata(L, plr->follower, META_MOBJ); // - + // rideroids else if (fastcmp(field,"rideroid")) lua_pushboolean(L, plr->rideroid); else if (fastcmp(field,"rdnodepull")) - lua_pushboolean(L, plr->rdnodepull); + lua_pushboolean(L, plr->rdnodepull); else if (fastcmp(field,"rideroidangle")) lua_pushinteger(L, plr->rideroidangle); else if (fastcmp(field,"rideroidspeed")) - lua_pushinteger(L, plr->rideroidspeed); + lua_pushinteger(L, plr->rideroidspeed); else if (fastcmp(field,"rideroidrollangle")) lua_pushinteger(L, plr->rideroidrollangle); else if (fastcmp(field,"rdaddmomx")) - lua_pushinteger(L, plr->rdaddmomx); + lua_pushinteger(L, plr->rdaddmomx); else if (fastcmp(field,"rdaddmomy")) - lua_pushinteger(L, plr->rdaddmomy); + lua_pushinteger(L, plr->rdaddmomy); else if (fastcmp(field,"rdaddmomz")) - lua_pushinteger(L, plr->rdaddmomz); - + lua_pushinteger(L, plr->rdaddmomz); + // bungee else if (fastcmp(field,"bungee")) - lua_pushinteger(L, plr->bungee); - + lua_pushinteger(L, plr->bungee); + // dlz hover else if (fastcmp(field,"lasthover")) - lua_pushinteger(L, plr->lasthover); - + lua_pushinteger(L, plr->lasthover); + // dlz rocket else if (fastcmp(field,"dlzrocket")) - lua_pushinteger(L, plr->dlzrocket); + lua_pushinteger(L, plr->dlzrocket); else if (fastcmp(field,"dlzrocketangle")) lua_pushinteger(L, plr->dlzrocketangle); else if (fastcmp(field,"dlzrocketanglev")) @@ -516,7 +516,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"seasawmoreangle")) lua_pushinteger(L, plr->seasawmoreangle); else if (fastcmp(field,"seasawdir")) - lua_pushboolean(L, plr->seasawdir); + lua_pushboolean(L, plr->seasawdir); // turbine else if (fastcmp(field,"turbine")) @@ -526,8 +526,8 @@ static int player_get(lua_State *L) else if (fastcmp(field,"turbineheight")) lua_pushinteger(L, plr->turbineheight); else if (fastcmp(field,"turbinespd")) - lua_pushinteger(L, plr->turbinespd); - + lua_pushinteger(L, plr->turbinespd); + else if (fastcmp(field,"charflags")) lua_pushinteger(L, plr->charflags); else if (fastcmp(field,"followitem")) @@ -932,7 +932,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"rdnodepull")) plr->rdnodepull = luaL_checkboolean(L, 3); else if (fastcmp(field,"rideroidangle")) - plr->rideroidangle = luaL_checkinteger(L, 3); + plr->rideroidangle = luaL_checkinteger(L, 3); else if (fastcmp(field,"rideroidspeed")) plr->rideroidspeed = luaL_checkinteger(L, 3); else if (fastcmp(field,"rideroidrollangle")) @@ -942,11 +942,11 @@ static int player_set(lua_State *L) else if (fastcmp(field,"rdaddmomy")) plr->rdaddmomy = luaL_checkinteger(L, 3); else if (fastcmp(field,"rdaddmomz")) - plr->rdaddmomz = luaL_checkinteger(L, 3); - + plr->rdaddmomz = luaL_checkinteger(L, 3); + // bungee else if (fastcmp(field,"bungee")) - plr->bungee = luaL_checkinteger(L, 3); + plr->bungee = luaL_checkinteger(L, 3); // dlz hover else if (fastcmp(field,"lasthover")) @@ -964,7 +964,7 @@ static int player_set(lua_State *L) // seasaws else if (fastcmp(field,"seasaw")) - plr->seasaw = luaL_checkboolean(L, 3); + plr->seasaw = luaL_checkboolean(L, 3); else if (fastcmp(field,"seasawcooldown")) plr->seasawcooldown = luaL_checkinteger(L, 3); else if (fastcmp(field,"seasawdist")) @@ -980,14 +980,14 @@ static int player_set(lua_State *L) // turbines else if (fastcmp(field,"turbine")) - plr->turbine = luaL_checkinteger(L, 3); + plr->turbine = luaL_checkinteger(L, 3); else if (fastcmp(field,"turbineangle")) plr->turbineangle = luaL_checkinteger(L, 3); else if (fastcmp(field,"turbineheight")) plr->turbineheight = luaL_checkinteger(L, 3); else if (fastcmp(field,"turbinespd")) - plr->turbinespd = luaL_checkinteger(L, 3); - + plr->turbinespd = luaL_checkinteger(L, 3); + // else if (fastcmp(field,"charflags")) plr->charflags = (UINT32)luaL_checkinteger(L, 3); diff --git a/src/p_inter.c b/src/p_inter.c index 7f940684c..8359fd91a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -764,7 +764,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } - + case MT_LSZ_BUNGEE: Obj_BungeeSpecial(special, player); return; @@ -820,11 +820,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_RAINBOWDASHRING: Obj_DashRingTouch(special, player); return; - + case MT_DLZ_ROCKET: Obj_DLZRocketSpecial(special, player); return; - + default: // SOC or script pickup P_SetTarget(&special->target, toucher); break; diff --git a/src/p_map.c b/src/p_map.c index cbf2c2a00..9de872678 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -741,31 +741,31 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) } // SRB2kart 011617 - Colission[sic] code for kart items // - + if (thing->type == MT_DLZ_SEASAW_HITBOX) { if (tm.thing->type == MT_PLAYER) Obj_DLZSeasawCollide(tm.thing, thing); // all checks are performed in there. - + return BMIT_CONTINUE; } - + if (thing->type == MT_DLZ_HOVER) { if (tm.thing->type == MT_PLAYER) Obj_DLZHoverCollide(tm.thing, thing); - + return BMIT_CONTINUE; } - + if (thing->type == MT_DLZ_RINGVACCUM) { if (tm.thing->type == MT_FLINGRING) Obj_DLZRingVaccumCollide(tm.thing, thing); - + return BMIT_CONTINUE; } - + if (tm.thing->type == MT_INSTAWHIP) { if (tm.thing->z > thing->z + thing->height) @@ -1901,7 +1901,7 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) else if (shouldCollide == 2) return BMIT_CONTINUE; // force no collide } - + // a bit of a hacky behaviour, but not that I know where else it would go. if (tm.blockingline->flags & ML_TFERLINE) { @@ -1914,7 +1914,7 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) Obj_DLZRocketDismount(tm.thing->player); } } - + if (!ld->backsector) // one sided line { if (P_PointOnLineSide(tm.thing->x, tm.thing->y, ld)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 08d8ef00a..f955e121e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9703,24 +9703,24 @@ 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; - + case MT_LSZ_EGGBALLSPAWNER: Obj_EggBallSpawnerThink(mobj); break; - + case MT_LSZ_EGGBALL: Obj_EggBallThink(mobj); break; @@ -9728,35 +9728,35 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_DLZ_ROCKET: Obj_DLZRocketThink(mobj); break; - + case MT_DLZ_SEASAW_SPAWN: Obj_DLZSeasawThink(mobj); break; - + case MT_DLZ_SUCKEDRING: Obj_DLZSuckedRingThink(mobj); break; - + case MT_WATERPALACETURBINE: Obj_WPZTurbineThinker(mobj); break; - + case MT_WATERPALACEBUBBLE: 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); diff --git a/src/p_saveg.c b/src/p_saveg.c index 95f9f4c6b..9f1ffeabf 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -554,7 +554,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].ringboxdelay); WRITEUINT8(save->p, players[i].ringboxaward); WRITEFIXED(save->p, players[i].outrun); - + WRITEUINT8(save->p, players[i].rideroid); WRITEUINT8(save->p, players[i].rdnodepull); WRITEINT32(save->p, players[i].rideroidangle); @@ -563,16 +563,16 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEFIXED(save->p, players[i].rdaddmomx); WRITEFIXED(save->p, players[i].rdaddmomy); WRITEFIXED(save->p, players[i].rdaddmomz); - + WRITEUINT8(save->p, players[i].bungee); - + WRITEUINT32(save->p, players[i].lasthover); - + WRITEUINT32(save->p, players[i].dlzrocket); WRITEANGLE(save->p, players[i].dlzrocketangle); WRITEINT32(save->p, players[i].dlzrocketanglev); WRITEUINT32(save->p, players[i].dlzrocketspd); - + WRITEUINT8(save->p, players[i].seasaw); WRITEUINT32(save->p, players[i].seasawcooldown); WRITEUINT32(save->p, players[i].seasawdist); @@ -580,12 +580,12 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT32(save->p, players[i].seasawangleadd); WRITEINT32(save->p, players[i].seasawmoreangle); WRITEUINT8(save->p, players[i].seasawdir); - + WRITEUINT32(save->p, players[i].turbine); WRITEINT32(save->p, players[i].turbineangle); WRITEFIXED(save->p, players[i].turbineheight); WRITEUINT8(save->p, players[i].turbinespd); - + // respawnvars_t WRITEUINT8(save->p, players[i].respawn.state); WRITEUINT32(save->p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -1064,7 +1064,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].ringboxdelay = READUINT8(save->p); players[i].ringboxaward = READUINT8(save->p); players[i].outrun = READFIXED(save->p); - + players[i].rideroid = READUINT8(save->p); players[i].rdnodepull = READUINT8(save->p); players[i].rideroidangle = READINT32(save->p); @@ -1073,16 +1073,16 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].rdaddmomx = READFIXED(save->p); players[i].rdaddmomy = READFIXED(save->p); players[i].rdaddmomz = READFIXED(save->p); - + players[i].bungee = READUINT8(save->p); - + players[i].lasthover = READUINT32(save->p); - + players[i].dlzrocket = READUINT32(save->p); players[i].dlzrocketangle = READANGLE(save->p); players[i].dlzrocketanglev = READINT32(save->p); players[i].dlzrocketspd = READUINT32(save->p); - + players[i].seasaw = READUINT8(save->p); players[i].seasawcooldown = READUINT32(save->p); players[i].seasawdist = READUINT32(save->p); From 5c57214e8ca23d18793d39759a713e524d8ae5f3 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:52:38 +0100 Subject: [PATCH 31/39] New player variables: Fix typing edge cases - p_saveg.c - lua_playerlib.c --- src/lua_playerlib.c | 12 ++++++------ src/p_saveg.c | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f7794197f..fa7c45d0e 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -938,11 +938,11 @@ static int player_set(lua_State *L) else if (fastcmp(field,"rideroidrollangle")) plr->rideroidrollangle = luaL_checkinteger(L, 3); else if (fastcmp(field,"rdaddmomx")) - plr->rdaddmomx = luaL_checkinteger(L, 3); + plr->rdaddmomx = luaL_checkfixed(L, 3); else if (fastcmp(field,"rdaddmomy")) - plr->rdaddmomy = luaL_checkinteger(L, 3); + plr->rdaddmomy = luaL_checkfixed(L, 3); else if (fastcmp(field,"rdaddmomz")) - plr->rdaddmomz = luaL_checkinteger(L, 3); + plr->rdaddmomz = luaL_checkfixed(L, 3); // bungee else if (fastcmp(field,"bungee")) @@ -960,7 +960,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"dlzrocketanglev")) plr->dlzrocketanglev = luaL_checkinteger(L, 3); else if (fastcmp(field,"dlzrocketspd")) - plr->dlzrocketspd = luaL_checkinteger(L, 3); + plr->dlzrocketspd = luaL_checkfixed(L, 3); // seasaws else if (fastcmp(field,"seasaw")) @@ -968,7 +968,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"seasawcooldown")) plr->seasawcooldown = luaL_checkinteger(L, 3); else if (fastcmp(field,"seasawdist")) - plr->seasawdist = luaL_checkinteger(L, 3); + plr->seasawdist = luaL_checkfixed(L, 3); else if (fastcmp(field,"seasawangle")) plr->seasawangle = luaL_checkinteger(L, 3); else if (fastcmp(field,"seasawangleadd")) @@ -984,7 +984,7 @@ static int player_set(lua_State *L) else if (fastcmp(field,"turbineangle")) plr->turbineangle = luaL_checkinteger(L, 3); else if (fastcmp(field,"turbineheight")) - plr->turbineheight = luaL_checkinteger(L, 3); + plr->turbineheight = luaL_checkfixed(L, 3); else if (fastcmp(field,"turbinespd")) plr->turbinespd = luaL_checkinteger(L, 3); diff --git a/src/p_saveg.c b/src/p_saveg.c index 9f1ffeabf..7d8cc3da8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -571,11 +571,11 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT32(save->p, players[i].dlzrocket); WRITEANGLE(save->p, players[i].dlzrocketangle); WRITEINT32(save->p, players[i].dlzrocketanglev); - WRITEUINT32(save->p, players[i].dlzrocketspd); + WRITEFIXED(save->p, players[i].dlzrocketspd); WRITEUINT8(save->p, players[i].seasaw); WRITEUINT32(save->p, players[i].seasawcooldown); - WRITEUINT32(save->p, players[i].seasawdist); + WRITEFIXED(save->p, players[i].seasawdist); WRITEINT32(save->p, players[i].seasawangle); WRITEINT32(save->p, players[i].seasawangleadd); WRITEINT32(save->p, players[i].seasawmoreangle); @@ -1065,8 +1065,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].ringboxaward = READUINT8(save->p); players[i].outrun = READFIXED(save->p); - players[i].rideroid = READUINT8(save->p); - players[i].rdnodepull = READUINT8(save->p); + players[i].rideroid = (boolean)READUINT8(save->p); + players[i].rdnodepull = (boolean)READUINT8(save->p); players[i].rideroidangle = READINT32(save->p); players[i].rideroidspeed = READFIXED(save->p); players[i].rideroidrollangle = READINT32(save->p); @@ -1076,25 +1076,25 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].bungee = READUINT8(save->p); - players[i].lasthover = READUINT32(save->p); + players[i].lasthover = (tic_t)READUINT32(save->p); - players[i].dlzrocket = READUINT32(save->p); + players[i].dlzrocket = (tic_t)READUINT32(save->p); players[i].dlzrocketangle = READANGLE(save->p); players[i].dlzrocketanglev = READINT32(save->p); - players[i].dlzrocketspd = READUINT32(save->p); + players[i].dlzrocketspd = READFIXED(save->p); - players[i].seasaw = READUINT8(save->p); + players[i].seasaw = (boolean)READUINT8(save->p); players[i].seasawcooldown = READUINT32(save->p); - players[i].seasawdist = READUINT32(save->p); + players[i].seasawdist = READFIXED(save->p); players[i].seasawangle = READINT32(save->p); players[i].seasawangleadd = READINT32(save->p); players[i].seasawmoreangle = READINT32(save->p); - players[i].seasawdir = READUINT8(save->p); + players[i].seasawdir = (boolean)READUINT8(save->p); - players[i].turbine = READUINT32(save->p); + players[i].turbine = (tic_t)READUINT32(save->p); players[i].turbineangle = READINT32(save->p); players[i].turbineheight = READFIXED(save->p); - players[i].turbinespd = READUINT8(save->p); + players[i].turbinespd = (boolean)READUINT8(save->p); // respawnvars_t players[i].respawn.state = READUINT8(save->p); From 4a2f3745f068f41ffacb885690fbae1e739dd06d Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 22:53:44 +0100 Subject: [PATCH 32/39] P_MobjRegularThink for new objects: Return early if certain objects that self-delete do so on this frame --- src/p_mobj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index f955e121e..7aa6ea7fe 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9723,10 +9723,18 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_LSZ_EGGBALL: Obj_EggBallThink(mobj); + if (P_MobjWasRemoved(mobj)) + { + return false; + } break; case MT_DLZ_ROCKET: Obj_DLZRocketThink(mobj); + if (P_MobjWasRemoved(mobj)) + { + return false; + } break; case MT_DLZ_SEASAW_SPAWN: @@ -9735,6 +9743,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_DLZ_SUCKEDRING: Obj_DLZSuckedRingThink(mobj); + if (P_MobjWasRemoved(mobj)) + { + return false; + } break; case MT_WATERPALACETURBINE: @@ -9743,6 +9755,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_WATERPALACEBUBBLE: Obj_WPZBubbleThink(mobj); + if (P_MobjWasRemoved(mobj)) + { + return false; + } break; case MT_WATERPALACEFOUNTAIN: @@ -9755,6 +9771,10 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_KURAGENBOMB: Obj_WPZKuragenBombThink(mobj); + if (P_MobjWasRemoved(mobj)) + { + return false; + } break; default: From 1e86d661a588f3d5d1f40f33cdf6d973ca2faf89 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 7 Oct 2023 09:56:19 +0200 Subject: [PATCH 33/39] Change turbine fast speed criteria from 133 to 200% --- src/objects/wpzturbine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/wpzturbine.c b/src/objects/wpzturbine.c index 7ce18bfd4..7f32bbdae 100644 --- a/src/objects/wpzturbine.c +++ b/src/objects/wpzturbine.c @@ -166,7 +166,7 @@ void Obj_WPZTurbineThinker(mobj_t *mo) p->turbineheight = baseheight; p->turbinespd = false; - if (FixedDiv(p->speed, K_GetKartSpeed(p, false, false)) > FRACUNIT + FRACUNIT/3 // 133% speed + if (FixedDiv(p->speed, K_GetKartSpeed(p, false, false)) > FRACUNIT*2 // 200% speed && baseheight != sneakerheight) { p->turbineheight = sneakerheight; From 085c3c650ca4c968ca2139e4ae1f73024cbeec0e Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 7 Oct 2023 10:21:18 +0200 Subject: [PATCH 34/39] Fix DLZ seasaws snapping to floors/ceilings --- src/objects/dlzseasaw.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 36c7756aa..0536a04ea 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -34,8 +34,6 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) UINT8 i, j; angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90; - P_SetScale(mo, 2*mapobjectscale); - if (mo->tracer && !P_MobjWasRemoved(mo->tracer)) { mo->tracer->tics = 3; @@ -128,7 +126,10 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) mobj_t *ptr = mo; mobj_t *ptrp = mo; UINT8 i, j; - + + P_SetScale(mo, 2*mapobjectscale); + mo->destscale = 2*mapobjectscale; + // setup vars mo->extravalue1 = (INT32)mo->angle; From bb3d6668520f5d915e917937201f672cc19de397 Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 7 Oct 2023 10:24:14 +0200 Subject: [PATCH 35/39] Whitespaces --- src/objects/dlzseasaw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 0536a04ea..2e1cb142c 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -126,10 +126,10 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) mobj_t *ptr = mo; mobj_t *ptrp = mo; UINT8 i, j; - + P_SetScale(mo, 2*mapobjectscale); mo->destscale = 2*mapobjectscale; - + // setup vars mo->extravalue1 = (INT32)mo->angle; From baa668895aa1bac3e3a634d8d7fa7ba2c9117c5a Mon Sep 17 00:00:00 2001 From: Lat Date: Sat, 7 Oct 2023 12:22:53 +0200 Subject: [PATCH 36/39] Move transfer line dismount hack to linedef type 2005 --- src/objects/rideroid.c | 4 ++++ src/p_map.c | 13 ------------- src/p_spec.c | 20 +++++++++++++++++--- src/r_bsp.cpp | 1 + src/r_debug.cpp | 3 +++ 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/objects/rideroid.c b/src/objects/rideroid.c index 64ed0cc5c..d9d739b51 100644 --- a/src/objects/rideroid.c +++ b/src/objects/rideroid.c @@ -52,6 +52,8 @@ static void plr_resetRideroidVars(player_t *p) p->rdaddmomx = 0; p->rdaddmomy = 0; p->rdaddmomz = 0; + + P_SetTarget(&p->mo->tracer, NULL); } // kills the rideroid and removes it from the map. @@ -255,6 +257,8 @@ void Obj_RideroidThink(mobj_t *mo) // if we're here, we made it to the rideroid and we can use it, or something like that! + P_SetTarget(&p->mo->tracer, mo); // keep a reference of the rideroid in the player for convenience. + // calculate the maximum speed we can move at. // the values are a little arbitrary but they work for how little use these have. diff --git a/src/p_map.c b/src/p_map.c index 9f3afa154..dd23deae7 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1902,19 +1902,6 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld) return BMIT_CONTINUE; // force no collide } - // a bit of a hacky behaviour, but not that I know where else it would go. - if (tm.blockingline->flags & ML_TFERLINE) - { - if (tm.thing->type == MT_RIDEROID) - { - Obj_getPlayerOffRideroid(tm.thing); - } - else if (tm.thing->type == MT_PLAYER && tm.thing->player && tm.thing->player->dlzrocket) - { - Obj_DLZRocketDismount(tm.thing->player); - } - } - if (!ld->backsector) // one sided line { if (P_PointOnLineSide(tm.thing->x, tm.thing->y, ld)) diff --git a/src/p_spec.c b/src/p_spec.c index 599ee327f..b7654af55 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -46,6 +46,7 @@ #include "console.h" // CON_LogMessage #include "k_respawn.h" #include "k_terrain.h" +#include "k_objects.h" #include "acs/interface.h" #include "m_easing.h" @@ -1379,6 +1380,7 @@ boolean P_CanActivateSpecial(INT16 special) { case 2001: // Finish line case 2003: // Respawn line + case 2005: // Dismount Flying Object (always true here so that conditions are only kept on execution) { return true; } @@ -4466,6 +4468,18 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha } break; + case 2005: // Dismount Flying object + // the rideroid is a bit complex so it's the one controlling the player rather than the player controlling it. + // so it is the object needing to be checked for rather than the player + if (mo->player && mo->player->rideroid && mo->tracer + && !P_MobjWasRemoved(mo->tracer) && mo->tracer->type == MT_RIDEROID) + Obj_getPlayerOffRideroid(mo->tracer); + + // dlz rockets are simpler and are tied to the player hence why we check for the player here instead. + if (mo->player && mo->player->dlzrocket) + Obj_DLZRocketDismount(mo->player); + break; + default: break; } @@ -9279,9 +9293,9 @@ void T_Pusher(pusher_t *p) if (thing->angle - angle > ANGLE_180) thing->player->drawangle = angle - (angle - thing->angle) / 8; else - thing->player->drawangle = angle + (thing->angle - angle) / 8; + thing->player->drawangle = angle + (thing->angle - angle) / 8; //P_SetPlayerAngle(thing->player, thing->angle); - + } if (p->exclusive) @@ -9424,7 +9438,7 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset) viewPos->z - quake->epicenter->z ) - distBuffer; - + fixed_t distEase = FixedDiv(max(epidist, 0), quake->radius); distEase = min(distEase, FRACUNIT); ir = Easing_InCubic(distEase, ir, 0); diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index f4e11bad4..35e8e39ac 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -415,6 +415,7 @@ boolean R_IsDebugLine(seg_t *line) { case 2001: // Ring Racers: Finish Line case 2003: // Ring Racers: Respawn Line + case 2005: // Ring Racers: Dismount flying object Line return true; } } diff --git a/src/r_debug.cpp b/src/r_debug.cpp index 500816305..b4a767944 100644 --- a/src/r_debug.cpp +++ b/src/r_debug.cpp @@ -75,6 +75,9 @@ UINT8 R_DebugLineColor(const line_t *ld) case 2003: // Ring Racers: Respawn Line return alt ? 0x23 : 0x00; // red, white + + case 2005: // Ring Racers: Dismount flying object Line + return alt ? 0x86 : 0x36; // blue, orange } return 0x00; From b2bbde290b95a2f24e726b8141d17af6e53bb050 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 7 Oct 2023 22:06:23 +0100 Subject: [PATCH 37/39] Add shadow to MT_KURAGEN Hazard conveyance --- src/p_mobj.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 152f9cbe6..12fe75e93 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10686,6 +10686,9 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) case MT_SNEAKERPANEL: thing->shadowscale = 0; break; + case MT_KURAGEN: + thing->shadowscale = FRACUNIT/4; + break; default: if (thing->flags & (MF_ENEMY|MF_BOSS)) thing->shadowscale = FRACUNIT; From dbcb39d7eda9a6fa07f61c30ce7650fef3525f92 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 7 Oct 2023 23:15:27 +0100 Subject: [PATCH 38/39] Fix Leaf Storm Eggball - Map object num was incorrectly copypasted onto the Dead Line Ring Vaccuum as well - Was getting destroyed instantly because its first spawnpoint is a deathpit. Now it only kills itself when it lands on a deathpit, not if it started on one - Use destscale instead of scaling every frame - Reduce duplicate P_IsObjectOnGround calls - Now has its own state --- src/deh_tables.c | 2 ++ src/info.c | 9 ++++++--- src/info.h | 3 +++ src/objects/eggball.c | 32 +++++++++++++++++--------------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 7d9a913cc..b73c08662 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4687,6 +4687,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_RIDEROID", "S_RIDEROID_ICON", + "S_EGGBALL", + "S_DLZHOVER", "S_DLZROCKET_L", "S_DLZROCKET_R", diff --git a/src/info.c b/src/info.c index f7445f536..13081cd12 100644 --- a/src/info.c +++ b/src/info.c @@ -5459,6 +5459,9 @@ state_t states[NUMSTATES] = {SPR_RDRD, 0, -1, {NULL}, 0, 0, S_RIDEROID}, // S_RIDEROID {SPR_RDRC, FF_ANIMATE|FF_FULLBRIGHT|FF_TRANS30, -1, {NULL}, 3, 2, S_RIDEROID_ICON}, // S_RIDEROID_ICON + // Leaf Storm + {SPR_LSZB, 0, -1, {NULL}, 0, 0, S_EGGBALL}, // S_EGGBALL + // Dead Line {SPR_DLZH, 0, -1, {NULL}, 0, 0, S_DLZHOVER}, // S_DLZHOVER @@ -30603,8 +30606,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_LSZ_EGGBALL - -1, // doomednum - S_INVISIBLE, // spawnstate + -1, // doomednum + S_EGGBALL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -30765,7 +30768,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_DLZ_RINGVACCUM, - 3443, // doomednum + 3433, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate diff --git a/src/info.h b/src/info.h index f1429d47e..3400928ed 100644 --- a/src/info.h +++ b/src/info.h @@ -5884,6 +5884,9 @@ typedef enum state S_RIDEROID, S_RIDEROID_ICON, + // leaf storm + S_EGGBALL, + // dead line zone S_DLZHOVER, S_DLZROCKET_L, diff --git a/src/objects/eggball.c b/src/objects/eggball.c index 4a74e3647..81edd1db1 100644 --- a/src/objects/eggball.c +++ b/src/objects/eggball.c @@ -31,12 +31,14 @@ // spawns balls every BALLMINSPAWNTIME to BALLMAXSPAWNTIME seconds. void Obj_EggBallSpawnerThink(mobj_t *mo) { - if (!mo->extravalue1) { mobj_t *ball = P_SpawnMobj(mo->x, mo->y, mo->z, MT_LSZ_EGGBALL); - ball->angle = mo->angle; - P_SetScale(ball, 6*mapobjectscale); + if (P_MobjWasRemoved(ball) == false) + { + ball->angle = mo->angle; + P_SetScale(ball, (ball->destscale = 6*mapobjectscale)); + } mo->extravalue1 = P_RandomRange(PR_TRACKHAZARD, TICRATE*BALLMINSPAWNTIME, TICRATE*BALLMAXSPAWNTIME); } @@ -50,13 +52,17 @@ void Obj_EggBallSpawnerThink(mobj_t *mo) void Obj_EggBallThink(mobj_t *mo) { + const boolean onground = P_IsObjectOnGround(mo); - P_SetScale(mo, 6*mapobjectscale); - - if (mo->eflags & MFE_JUSTHITFLOOR - && mo->threshold) + if (mo->eflags & MFE_JUSTHITFLOOR) { - if (mo->threshold < -10*mapobjectscale) + if (mo->extravalue1 && P_CheckDeathPitCollide(mo)) + { + P_RemoveMobj(mo); + return; + } + + if (mo->threshold && mo->threshold < -10*mapobjectscale) { UINT8 i; @@ -80,17 +86,16 @@ void Obj_EggBallThink(mobj_t *mo) if (!mo->extravalue1) { - if (P_IsObjectOnGround(mo)) + if (onground) { mo->extravalue1 = 1; mo->cusval = 24*mapobjectscale; mo->movedir = mo->z; - mo->sprite = SPR_LSZB; } } else { - if (P_IsObjectOnGround(mo) && mo->extravalue2 &1) + if (onground && (mo->extravalue2 & 1)) { fixed_t dx = mo->x + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momx*2; fixed_t dy = mo->y + P_RandomRange(PR_DECORATION, -96, 96)*mapobjectscale - mo->momy*2; @@ -107,7 +112,7 @@ void Obj_EggBallThink(mobj_t *mo) mo->frame = mo->extravalue2 % (24 * 2) / 2; // 24 is for frame Y. // build up speed - if (P_IsObjectOnGround(mo)) + if (onground) { if (mo->eflags & MFE_VERTICALFLIP) { @@ -128,7 +133,4 @@ void Obj_EggBallThink(mobj_t *mo) mo->movedir = mo->z; } mo->threshold = mo->momz; - - if (P_CheckDeathPitCollide(mo)) - P_RemoveMobj(mo); } From 756f42bc26509afa9a5a8775240c1f8c17d40737 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 7 Oct 2023 23:26:53 +0100 Subject: [PATCH 39/39] Fix DLZ Ring Sucker effect - Fix infinite loop caused by not actually using the intended object type - Fix integer multiply of two fixed-scale numbers causing overflow --- src/objects/dlzothers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/objects/dlzothers.c b/src/objects/dlzothers.c index 90c5ab331..d4d9f8f31 100644 --- a/src/objects/dlzothers.c +++ b/src/objects/dlzothers.c @@ -90,7 +90,7 @@ void Obj_DLZRingVaccumCollide(mobj_t *mo, mobj_t *mo2) if (!P_IsObjectOnGround(mo) || mo->momz) return; - fake = P_SpawnMobj(mo->x, mo->y, mo->z, MT_FLINGRING); + fake = P_SpawnMobj(mo->x, mo->y, mo->z, MT_DLZ_SUCKEDRING); P_SetScale(fake, mo->scale); fake->scalespeed = mapobjectscale/64; fake->destscale = 1; @@ -115,8 +115,8 @@ void Obj_DLZSuckedRingThink(mobj_t *mo) return; } - x = t->x + mo->movefactor*FINECOSINE(mo->angle>>ANGLETOFINESHIFT); - y = t->y + mo->movefactor*FINESINE(mo->angle>>ANGLETOFINESHIFT); + x = t->x + FixedMul(mo->movefactor, FINECOSINE(mo->angle>>ANGLETOFINESHIFT)); + y = t->y + FixedMul(mo->movefactor, FINESINE(mo->angle>>ANGLETOFINESHIFT)); P_MoveOrigin(mo, x, y, mo->z);