From ff3826466be7f9141521bf22c414674fda72007f Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 19 Nov 2023 04:48:37 -0800 Subject: [PATCH 1/5] Rename MT_DLZ_SEASAW_VISUAL to MT_SEASAW_VISUAL, reorganize seasaw states In preparation for Gust Planet seasaws, I'm grouping these separately from the rest of Dead Line states. Because the visual object does no think for itself, rather by proxy of the main seasaw object: I removed the DLZ tag, since this object will be reused for Gust Planet. --- src/deh_tables.c | 7 +- src/info.c | 164 ++++++++++++++++++++-------------------- src/info.h | 7 +- src/objects/dlzseasaw.c | 2 +- 4 files changed, 91 insertions(+), 89 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 7fbf62af3..dd1463caa 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5971,9 +5971,6 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DLZ_HOVER", "MT_DLZ_ROCKET", - "MT_DLZ_SEASAW_SPAWN", - "MT_DLZ_SEASAW_HITBOX", - "MT_DLZ_SEASAW_VISUAL", "MT_DLZ_RINGVACCUM", "MT_DLZ_SUCKEDRING", @@ -5999,6 +5996,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BLENDEYE_PUYO_DUST", "MT_BLENDEYE_PUYO_DUST_COFFEE", "MT_MEGABARRIER", + + "MT_SEASAW_VISUAL", + "MT_DLZ_SEASAW_SPAWN", + "MT_DLZ_SEASAW_HITBOX", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 49ca2f610..66ddd21a8 100644 --- a/src/info.c +++ b/src/info.c @@ -31124,87 +31124,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 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|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - { // MT_DLZ_RINGVACCUM, 3433, // doomednum S_INVISIBLE, // spawnstate @@ -31770,7 +31689,88 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOSQUISH, // flags S_NULL // raisestate - } + }, + + { // MT_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|MF_NOCLIP|MF_NOCLIPHEIGHT, // 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 + }, }; diff --git a/src/info.h b/src/info.h index 90f80efcf..6a138ba17 100644 --- a/src/info.h +++ b/src/info.h @@ -7242,9 +7242,6 @@ typedef enum mobj_type MT_DLZ_HOVER, MT_DLZ_ROCKET, - MT_DLZ_SEASAW_SPAWN, - MT_DLZ_SEASAW_HITBOX, - MT_DLZ_SEASAW_VISUAL, MT_DLZ_RINGVACCUM, MT_DLZ_SUCKEDRING, @@ -7272,6 +7269,10 @@ typedef enum mobj_type MT_MEGABARRIER, + MT_SEASAW_VISUAL, + MT_DLZ_SEASAW_SPAWN, + MT_DLZ_SEASAW_HITBOX, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 14550eddb..8f887fb5d 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -151,7 +151,7 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) { // 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); + mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_SEASAW_VISUAL); vis->sprite = SPR_DLZS; vis->frame = (j+1)|FF_PAPERSPRITE; vis->tics = -1; From 920c6c03111775fd3ee3e20d69ca57301a9ffd25 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Nov 2023 01:06:06 -0800 Subject: [PATCH 2/5] Obj_DLZSeasawUpdate: fix eflags typo --- src/objects/dlzseasaw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects/dlzseasaw.c b/src/objects/dlzseasaw.c index 8f887fb5d..ede154e13 100644 --- a/src/objects/dlzseasaw.c +++ b/src/objects/dlzseasaw.c @@ -43,7 +43,7 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) if (mo->eflags & MFE_VERTICALFLIP) { mo->tracer->eflags |= MFE_VERTICALFLIP; - mo->tracer->eflags |= MF2_OBJECTFLIP; + mo->tracer->flags2 |= MF2_OBJECTFLIP; } } From 8961eef681546e65bae7daa3f4b839bfcbf3c3eb Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 20 Nov 2023 23:37:53 -0800 Subject: [PATCH 3/5] Carbon copy objects/dlzseasaw.c -> objects/gpzseasaw.c --- src/objects/gpzseasaw.c | 367 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 src/objects/gpzseasaw.c diff --git a/src/objects/gpzseasaw.c b/src/objects/gpzseasaw.c new file mode 100644 index 000000000..ede154e13 --- /dev/null +++ b/src/objects/gpzseasaw.c @@ -0,0 +1,367 @@ +// 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; + + 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->flags2 |= 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++) + { + // 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 (mo->eflags & MFE_VERTICALFLIP) + { + ptr->eflags |= MFE_VERTICALFLIP; + ptr->flags2 |= MF2_OBJECTFLIP; + } + + 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; + + + if (mo->eflags & MFE_VERTICALFLIP) + { + ptrp->eflags |= MFE_VERTICALFLIP; + ptrp->flags2 |= MF2_OBJECTFLIP; + } + + 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; + + P_SetScale(mo, 2*mapobjectscale); + mo->destscale = 2*mapobjectscale; + + // 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_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); + + K_SetTireGrease(p, 3*TICRATE); + + 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; + + // 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)) + 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); +} From 4b3ea7460bd823b084b08d67623a4aa869adf018 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Nov 2023 01:03:57 -0800 Subject: [PATCH 4/5] Hardcode Gust Planet seasaws - Add states - MT_GPZ_SEASAW_SPAWN - MT_GPZ_SEASAW_HITBOX - SPR_GPPS - SPR_GPZS - Add objects API - Obj_GPZSeasawSpawn - Obj_GPZSeasawThink - Obj_GPZSeasawCollide - objects/gpzseasaw.c - Gust Planet seasaw behavior --- src/deh_tables.c | 2 + src/info.c | 58 +++++++ src/info.h | 6 + src/k_objects.h | 15 +- src/objects/CMakeLists.txt | 1 + src/objects/gpzseasaw.c | 336 ++++++++++++++++++------------------- src/p_map.c | 8 + src/p_mobj.c | 21 ++- 8 files changed, 261 insertions(+), 186 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index dd1463caa..0fcf92eeb 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6000,6 +6000,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SEASAW_VISUAL", "MT_DLZ_SEASAW_SPAWN", "MT_DLZ_SEASAW_HITBOX", + "MT_GPZ_SEASAW_SPAWN", + "MT_GPZ_SEASAW_HITBOX", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 66ddd21a8..3edce031f 100644 --- a/src/info.c +++ b/src/info.c @@ -968,6 +968,10 @@ char sprnames[NUMSPRITES + 1][5] = "MGSH", // Mega Barrier + // GPZ Seasaw + "GPPS", + "GPZS", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -31771,6 +31775,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SOLID, // flags S_NULL // raisestate }, + + { // MT_GPZ_SEASAW_SPAWN, + 3435, // 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_GPZ_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 + }, }; diff --git a/src/info.h b/src/info.h index 6a138ba17..f043c6c3f 100644 --- a/src/info.h +++ b/src/info.h @@ -1522,6 +1522,10 @@ typedef enum sprite SPR_MGSH, // Mega Barrier + // GPZ Seasaw + SPR_GPPS, + SPR_GPZS, + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -7272,6 +7276,8 @@ typedef enum mobj_type MT_SEASAW_VISUAL, MT_DLZ_SEASAW_SPAWN, MT_DLZ_SEASAW_HITBOX, + MT_GPZ_SEASAW_SPAWN, + MT_GPZ_SEASAW_HITBOX, MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, diff --git a/src/k_objects.h b/src/k_objects.h index 8a95e414d..a116b96ea 100644 --- a/src/k_objects.h +++ b/src/k_objects.h @@ -261,11 +261,6 @@ 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); - /* DLZ Hover */ void Obj_DLZHoverSpawn(mobj_t *mo); void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2); @@ -298,6 +293,16 @@ void Obj_BallSwitchDamaged(mobj_t *mobj, mobj_t *inflictor, mobj_t *source); void Obj_SpawnMegaBarrier(player_t *player); boolean Obj_MegaBarrierThink(mobj_t *mobj); +/* DLZ Seasaw */ +void Obj_DLZSeasawSpawn(mobj_t *mo); +void Obj_DLZSeasawThink(mobj_t *mo); +void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2); + +/* GPZ Seasaw */ +void Obj_GPZSeasawSpawn(mobj_t *mo); +void Obj_GPZSeasawThink(mobj_t *mo); +void Obj_GPZSeasawCollide(mobj_t *mo, mobj_t *mo2); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/objects/CMakeLists.txt b/src/objects/CMakeLists.txt index 2bd4a38b3..96182b5ea 100644 --- a/src/objects/CMakeLists.txt +++ b/src/objects/CMakeLists.txt @@ -34,6 +34,7 @@ target_sources(SRB2SDL2 PRIVATE eggball.c dlzrocket.c dlzseasaw.c + gpzseasaw.c dlzothers.c wpzturbine.c wpzothers.c diff --git a/src/objects/gpzseasaw.c b/src/objects/gpzseasaw.c index ede154e13..d20061f08 100644 --- a/src/objects/gpzseasaw.c +++ b/src/objects/gpzseasaw.c @@ -7,8 +7,8 @@ // 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! +/// \file gpzseasaw.c +/// \brief Gust Planet Zone seasaw. Similar to Dead Line version, but with notable differences. #include "../doomdef.h" #include "../doomstat.h" @@ -26,12 +26,12 @@ #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) +static void Obj_GPZSeasawUpdate(mobj_t *mo, boolean ghostme) { mobj_t *ptr = mo; mobj_t *ptrp = mo; - UINT8 i, j; + UINT8 j; angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90; if (mo->tracer && !P_MobjWasRemoved(mo->tracer)) @@ -48,84 +48,99 @@ static void Obj_DLZSeasawUpdate(mobj_t *mo, boolean ghostme) } + fixed_t cx = mo->x + FixedMul(mo->scale, 96*FINECOSINE(visan>>ANGLETOFINESHIFT)); + fixed_t cy = mo->y + FixedMul(mo->scale, 96*FINESINE(visan>>ANGLETOFINESHIFT)); - for (i = 0; i < 2; i++) + INT32 hdist = 64; // hitbox dist + + angle_t tun_an = visan; + + // visuals + for (j = 0; j < 4; j++) { - 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)) { - // get our mobj. - if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext)) + tun_an += ANGLE_90; + + fixed_t x = cx + FixedMul(mo->scale, 32*FINECOSINE(tun_an>>ANGLETOFINESHIFT)); + fixed_t y = cy + FixedMul(mo->scale, 32*FINESINE(tun_an>>ANGLETOFINESHIFT)); + ptr = ptr->hnext; + + P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); + ptr->angle = tun_an + ANGLE_90; + ptr->tics = 3; + P_SetScale(ptr, 2 * mo->scale); + + if (mo->eflags & MFE_VERTICALFLIP) { - 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; + ptr->eflags |= MFE_VERTICALFLIP; + ptr->flags2 |= MF2_OBJECTFLIP; + } - P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); - 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) - { - mobj_t *g = P_SpawnGhostMobj(ptr); - g->colorized = true; - g->color = mo->color; - g->fuse = 3; - } - - dist += 55; + if (ghostme && leveltime&1) + { + mobj_t *g = P_SpawnGhostMobj(ptr); + g->colorized = true; + g->color = mo->color; + g->fuse = 3; } } - // hitboxes: - for (j = 0; j < 8; j++) + // get our mobj. + if (ptrp && !P_MobjWasRemoved(ptrp) && ptrp->hprev && !P_MobjWasRemoved(ptrp->hprev)) { - // 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; + + + if (mo->eflags & MFE_VERTICALFLIP) { - - 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; - - - if (mo->eflags & MFE_VERTICALFLIP) - { - ptrp->eflags |= MFE_VERTICALFLIP; - ptrp->flags2 |= MF2_OBJECTFLIP; - } - - hdist += 16; + ptrp->eflags |= MFE_VERTICALFLIP; + ptrp->flags2 |= MF2_OBJECTFLIP; } + hdist += 16; } + } - visan += ANGLE_180; + // center thingy + ptr = ptr->hnext; + + P_MoveOrigin(ptr, cx, cy, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); + ptr->angle = visan + ANGLE_90; + ptr->tics = 3; + P_SetScale(ptr, 2 * mo->scale); + + if (mo->eflags & MFE_VERTICALFLIP) + { + ptr->eflags |= MFE_VERTICALFLIP; + ptr->flags2 |= MF2_OBJECTFLIP; + } + + if (ghostme && leveltime&1) + { + mobj_t *g = P_SpawnGhostMobj(ptr); + g->colorized = true; + g->color = mo->color; + g->fuse = 3; } } // sets up seasaw spawn objects to update each frame later -void Obj_DLZSeasawSpawn(mobj_t *mo) +void Obj_GPZSeasawSpawn(mobj_t *mo) { mobj_t *pole; mobj_t *ptr = mo; mobj_t *ptrp = mo; - UINT8 i, j; + UINT8 j; P_SetScale(mo, 2*mapobjectscale); mo->destscale = 2*mapobjectscale; @@ -136,7 +151,7 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) // center pole: pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); pole->tics = -1; - pole->sprite = SPR_DLZS; + pole->sprite = SPR_GPPS; pole->frame = 0; P_SetTarget(&pole->target, mo); P_SetTarget(&mo->tracer, pole); @@ -144,62 +159,72 @@ void Obj_DLZSeasawSpawn(mobj_t *mo) if (mo->eflags & MFE_VERTICALFLIP) pole->eflags |= MFE_VERTICALFLIP; + int frame_lookup[4] = {0, 3, 1, 3}; // A D B D // spawn visuals / hitboxes. - for (i = 0; i < 2; i++) // for each side... + for (j = 0; j < 4; j++) // spawn both ends of the "tunnel" and the sides! { - 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_SEASAW_VISUAL); + vis->sprite = SPR_GPZS; + vis->frame = frame_lookup[j]|FF_PAPERSPRITE; + vis->tics = -1; + + if (mo->eflags & MFE_VERTICALFLIP) { - // 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_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; + vis->eflags |= MFE_VERTICALFLIP; + vis->flags2 |= MF2_OBJECTFLIP; } - for (j = 0; j < 8; j++) // spawn the 8 hitboxes on each side. + P_SetTarget(&vis->target, mo); + P_SetTarget(&ptr->hnext, vis); // save in an hnext list for updating later. + ptr = vis; + + // --- + + mobj_t *h = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_GPZ_SEASAW_HITBOX); + h->tics = -1; + + if (mo->eflags & MFE_VERTICALFLIP) { - // 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; + 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; } + // finally, spawn the last thingy at the center: + mobj_t *vis = P_SpawnMobj(mo->x, mo->y, mo->z + 8*mapobjectscale*P_MobjFlip(mo), MT_SEASAW_VISUAL); + vis->sprite = SPR_GPZS; + vis->frame = 2|FF_PAPERSPRITE; // C + 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; + // update after spawning the objects so that they appear in the right spot when the map loads. - Obj_DLZSeasawUpdate(mo, false); + Obj_GPZSeasawUpdate(mo, false); } -static void Obj_DLZSeasawReset(mobj_t *mo) +static void Obj_GPZSeasawReset(mobj_t *mo) { mo->extravalue1 = (INT32)mo->angle; P_SetTarget(&mo->target, NULL); - Obj_DLZSeasawUpdate(mo, false); + Obj_GPZSeasawUpdate(mo, false); } // main seasaw thinker. -void Obj_DLZSeasawThink(mobj_t *mo) +void Obj_GPZSeasawThink(mobj_t *mo) { boolean ghost = false; SINT8 rot = 1; @@ -212,73 +237,44 @@ void Obj_DLZSeasawThink(mobj_t *mo) if (!p) // untarget this instantly. { - Obj_DLZSeasawReset(mo); + Obj_GPZSeasawReset(mo); return; } if (!mo->extravalue2) rot = -1; - // first half of the animation... - if (!p->seasawdir) + INT32 angleadd = ANG1*max(4, (3*mo->movefactor/4)/(mapobjectscale*2)) * rot; + + p->seasawcooldown = TICRATE/2; + + mo->extravalue1 += angleadd; + p->seasawangle += angleadd; + + p->seasawangleadd += max(4, (3*mo->movefactor/4)/(mapobjectscale*2)); + P_SetPlayerAngle(p, (angle_t)(p->seasawangle + ANGLE_90*rot)); + //t->angle = p->seasawangle + ANGLE_90*rot; + + p->seasawdist = (184 * mapobjectscale) / FRACUNIT; + + if (p->seasawangleadd >= 360) // we did a full turn! { - INT32 angleadd = ANG1*max(4, (mo->movefactor/3)/mapobjectscale) * rot; + // reset everything and send the player zooming + Obj_GPZSeasawReset(mo); - if (p->seasawangleadd > 175) - angleadd /= max(1, (p->seasawangleadd - 160)/8); + angle_t thrust_angle = mo->threshold ? mo->angle + ANGLE_180 : mo->angle; + P_SetPlayerAngle(p, thrust_angle); + P_MoveOrigin(t, t->x, t->y, t->z); // miscall that to set the position properly. + P_InstaThrust(t, thrust_angle, mo->movefactor*3); // send the player flying at triple the speed they came at us with. + S_StartSound(t, sfx_s3kb6); - mo->extravalue1 += angleadd; - p->seasawangle += angleadd; + p->seasawangleadd = 0; + p->seasawangle = 0; + p->seasawmoreangle = 0; + p->seasaw = false; - 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); - - K_SetTireGrease(p, 3*TICRATE); - - p->seasawangleadd = 0; - p->seasawangle = 0; - p->seasawmoreangle = 0; - p->seasaw = false; - - Obj_DLZSeasawUpdate(mo, true); - return; - - } + Obj_GPZSeasawUpdate(mo, true); + return; } // update the player px = mo->x + p->seasawdist*FINECOSINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT); @@ -287,10 +283,10 @@ void Obj_DLZSeasawThink(mobj_t *mo) P_MoveOrigin(t, px, py, mo->z + mapobjectscale*8); } else - Obj_DLZSeasawReset(mo); + Obj_GPZSeasawReset(mo); // finally, update the visuals. - Obj_DLZSeasawUpdate(mo, ghost); + Obj_GPZSeasawUpdate(mo, ghost); } // ported just for convenience of not needing to rewrite the code to account for UINT32 angles... @@ -302,11 +298,10 @@ static INT32 angtoint(angle_t a) // 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) +void Obj_GPZSeasawCollide(mobj_t *mo, mobj_t *mo2) { player_t *p = mo->player; INT32 momangle; - boolean invert = false; // cooldown / respawning if (p->seasawcooldown || p->respawn.timer) @@ -336,32 +331,25 @@ void Obj_DLZSeasawCollide(mobj_t *mo, mobj_t *mo2) //CONS_Printf("%d / %d -> %d\n", momangle, angtoint(mo2->target->angle), (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180))); + int side = mo2->target->spawnpoint && (mo2->target->spawnpoint->options & 1); + // 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->threshold = (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180) > 60); 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; + mo2->target->extravalue2 = side ^ mo2->target->threshold; // which side of the pole are we on? 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->seasawdist = (128 * mapobjectscale) / FRACUNIT; + p->seasawangle = mo2->target->angle + (side ? ANGLE_270 : ANGLE_90); p->seasawangleadd = 0; p->seasawdir = false; p->seasaw = true; p->pflags |= PF_STASIS; p->seasawcooldown = TICRATE/2; - S_StartSound(mo, sfx_s3k88); + S_StartSound(mo, sfx_s3k3c); } diff --git a/src/p_map.c b/src/p_map.c index 5e68afc21..954aca720 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -724,6 +724,14 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing) return BMIT_CONTINUE; } + if (thing->type == MT_GPZ_SEASAW_HITBOX) + { + if (tm.thing->type == MT_PLAYER) + Obj_GPZSeasawCollide(tm.thing, thing); // all checks are performed in there. + + return BMIT_CONTINUE; + } + if (thing->type == MT_DLZ_HOVER) { if (tm.thing->type == MT_PLAYER) diff --git a/src/p_mobj.c b/src/p_mobj.c index 990758b8b..4b156a7c6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10137,10 +10137,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; - case MT_DLZ_SEASAW_SPAWN: - Obj_DLZSeasawThink(mobj); - break; - case MT_DLZ_SUCKEDRING: Obj_DLZSuckedRingThink(mobj); if (P_MobjWasRemoved(mobj)) @@ -10177,6 +10173,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; + case MT_DLZ_SEASAW_SPAWN: + Obj_DLZSeasawThink(mobj); + break; + + case MT_GPZ_SEASAW_SPAWN: + Obj_GPZSeasawThink(mobj); + break; + case MT_BALLSWITCH_BALL: { Obj_BallSwitchThink(mobj); @@ -11635,9 +11639,6 @@ 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_SEASAW_SPAWN: - Obj_DLZSeasawSpawn(mobj); - break; case MT_DLZ_HOVER: Obj_DLZHoverSpawn(mobj); break; @@ -11674,6 +11675,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) case MT_BLENDEYE_PUYO_DUST: mobj->sprite = mobj->movedir = P_RandomRange(PR_DECORATION, SPR_PUYA, SPR_PUYE); break; + case MT_DLZ_SEASAW_SPAWN: + Obj_DLZSeasawSpawn(mobj); + break; + case MT_GPZ_SEASAW_SPAWN: + Obj_GPZSeasawSpawn(mobj); + break; default: break; } From 0c57902463b811afface014985914de01e1a9fe6 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 19 Nov 2023 05:36:59 -0800 Subject: [PATCH 5/5] Hardcode Gust Planet "Trees" --- src/deh_tables.c | 8 +++++ src/info.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 13 +++++++ 3 files changed, 111 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 0fcf92eeb..b29e08394 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4791,6 +4791,10 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_MEGABARRIER1", "S_MEGABARRIER2", "S_MEGABARRIER3", + + "S_GPZ_TREETHING_B", + "S_GPZ_TREETHING_M", + "S_GPZ_TREETHING_S", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -6002,6 +6006,10 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_DLZ_SEASAW_HITBOX", "MT_GPZ_SEASAW_SPAWN", "MT_GPZ_SEASAW_HITBOX", + + "MT_GPZ_TREETHING_B", + "MT_GPZ_TREETHING_M", + "MT_GPZ_TREETHING_S", }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/info.c b/src/info.c index 3edce031f..74d760f2f 100644 --- a/src/info.c +++ b/src/info.c @@ -972,6 +972,11 @@ char sprnames[NUMSPRITES + 1][5] = "GPPS", "GPZS", + // Gust Planet Trees + "GPTB", + "GPTM", + "GPTS", + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later "VIEW", }; @@ -5623,6 +5628,10 @@ state_t states[NUMSTATES] = {SPR_MGSH, 2|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER1, {SPR_MGSH, 1|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER2, {SPR_MGSH, 0|FF_PAPERSPRITE|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_MEGABARRIER3, + + {SPR_GPTB, 0, -1, {A_SetScale}, 4*FRACUNIT, 0, S_NULL}, // S_GPZ_TREETHING_B, + {SPR_GPTM, 0, -1, {A_SetScale}, 4*FRACUNIT, 0, S_NULL}, // S_GPZ_TREETHING_M, + {SPR_GPTS, 0, -1, {A_SetScale}, 4*FRACUNIT, 0, S_NULL}, // S_GPZ_TREETHING_S, }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -31829,6 +31838,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SOLID, // flags S_NULL // raisestate }, + + { // MT_GPZ_TREETHING_B, + 3436, // doomednum + S_GPZ_TREETHING_B, // 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 + 40*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_GPZ_TREETHING_M, + 3437, // doomednum + S_GPZ_TREETHING_M, // 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 + 40*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, + + { // MT_GPZ_TREETHING_S, + 3438, // doomednum + S_GPZ_TREETHING_M, // 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 + 40*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_RUNSPAWNFUNC, // flags + S_NULL // raisestate + }, }; diff --git a/src/info.h b/src/info.h index f043c6c3f..53a9e62fd 100644 --- a/src/info.h +++ b/src/info.h @@ -1526,6 +1526,11 @@ typedef enum sprite SPR_GPPS, SPR_GPZS, + // Gust Planet Trees + SPR_GPTB, + SPR_GPTM, + SPR_GPTS, + // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later SPR_VIEW, @@ -6048,6 +6053,10 @@ typedef enum state S_MEGABARRIER2, S_MEGABARRIER3, + S_GPZ_TREETHING_B, + S_GPZ_TREETHING_M, + S_GPZ_TREETHING_S, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES @@ -7279,6 +7288,10 @@ typedef enum mobj_type MT_GPZ_SEASAW_SPAWN, MT_GPZ_SEASAW_HITBOX, + MT_GPZ_TREETHING_B, + MT_GPZ_TREETHING_M, + MT_GPZ_TREETHING_S, + MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, NUMMOBJTYPES