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
This commit is contained in:
James R 2023-11-21 01:03:57 -08:00
parent 8961eef681
commit 4b3ea7460b
8 changed files with 261 additions and 186 deletions

View file

@ -6000,6 +6000,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t
"MT_SEASAW_VISUAL", "MT_SEASAW_VISUAL",
"MT_DLZ_SEASAW_SPAWN", "MT_DLZ_SEASAW_SPAWN",
"MT_DLZ_SEASAW_HITBOX", "MT_DLZ_SEASAW_HITBOX",
"MT_GPZ_SEASAW_SPAWN",
"MT_GPZ_SEASAW_HITBOX",
}; };
const char *const MOBJFLAG_LIST[] = { const char *const MOBJFLAG_LIST[] = {

View file

@ -968,6 +968,10 @@ char sprnames[NUMSPRITES + 1][5] =
"MGSH", // Mega Barrier "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 // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
"VIEW", "VIEW",
}; };
@ -31771,6 +31775,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_SOLID, // flags MF_SOLID, // flags
S_NULL // raisestate 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
},
}; };

View file

@ -1522,6 +1522,10 @@ typedef enum sprite
SPR_MGSH, // Mega Barrier 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 // First person view sprites; this is a sprite so that it can be replaced by a specialized MD2 draw later
SPR_VIEW, SPR_VIEW,
@ -7272,6 +7276,8 @@ typedef enum mobj_type
MT_SEASAW_VISUAL, MT_SEASAW_VISUAL,
MT_DLZ_SEASAW_SPAWN, MT_DLZ_SEASAW_SPAWN,
MT_DLZ_SEASAW_HITBOX, MT_DLZ_SEASAW_HITBOX,
MT_GPZ_SEASAW_SPAWN,
MT_GPZ_SEASAW_HITBOX,
MT_FIRSTFREESLOT, MT_FIRSTFREESLOT,
MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1,

View file

@ -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_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. 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 */ /* DLZ Hover */
void Obj_DLZHoverSpawn(mobj_t *mo); void Obj_DLZHoverSpawn(mobj_t *mo);
void Obj_DLZHoverCollide(mobj_t *mo, mobj_t *mo2); 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); void Obj_SpawnMegaBarrier(player_t *player);
boolean Obj_MegaBarrierThink(mobj_t *mobj); 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 #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View file

@ -34,6 +34,7 @@ target_sources(SRB2SDL2 PRIVATE
eggball.c eggball.c
dlzrocket.c dlzrocket.c
dlzseasaw.c dlzseasaw.c
gpzseasaw.c
dlzothers.c dlzothers.c
wpzturbine.c wpzturbine.c
wpzothers.c wpzothers.c

View file

@ -7,8 +7,8 @@
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details. // See the 'LICENSE' file for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file dlzseasaw.c /// \file gpzseasaw.c
/// \brief Dead Line Zone seasaw. Amplifies momentum in a stylish way... and hellish as far as code is concerned, heh! /// \brief Gust Planet Zone seasaw. Similar to Dead Line version, but with notable differences.
#include "../doomdef.h" #include "../doomdef.h"
#include "../doomstat.h" #include "../doomstat.h"
@ -26,12 +26,12 @@
#include "../k_collide.h" #include "../k_collide.h"
// updates the seasaw's visuals and hitboxes using the hnext/hprev list. // 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 *ptr = mo;
mobj_t *ptrp = mo; mobj_t *ptrp = mo;
UINT8 i, j; UINT8 j;
angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90; angle_t visan = (angle_t)mo->extravalue1 + ANGLE_90;
if (mo->tracer && !P_MobjWasRemoved(mo->tracer)) 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 // get our mobj.
INT32 hdist = 16; // hitbox dist if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext))
// visuals
for (j = 0; j < 2; j++)
{ {
// get our mobj. tun_an += ANGLE_90;
if (ptr && !P_MobjWasRemoved(ptr) && ptr->hnext && !P_MobjWasRemoved(ptr->hnext))
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)); ptr->eflags |= MFE_VERTICALFLIP;
fixed_t y = mo->y + FixedMul(mo->scale, dist*FINESINE(visan>>ANGLETOFINESHIFT)); ptr->flags2 |= MF2_OBJECTFLIP;
ptr = ptr->hnext; }
P_MoveOrigin(ptr, x, y, mo->z + 8*mapobjectscale*P_MobjFlip(mo)); if (ghostme && leveltime&1)
ptr->angle = visan; {
ptr->tics = 3; mobj_t *g = P_SpawnGhostMobj(ptr);
P_SetScale(ptr, mo->scale); g->colorized = true;
g->color = mo->color;
if (mo->eflags & MFE_VERTICALFLIP) g->fuse = 3;
{
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: // get our mobj.
for (j = 0; j < 8; j++) 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)
{ {
ptrp->eflags |= MFE_VERTICALFLIP;
fixed_t x = mo->x + FixedMul(mo->scale, hdist*FINECOSINE(visan>>ANGLETOFINESHIFT)); ptrp->flags2 |= MF2_OBJECTFLIP;
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;
} }
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 // 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 *pole;
mobj_t *ptr = mo; mobj_t *ptr = mo;
mobj_t *ptrp = mo; mobj_t *ptrp = mo;
UINT8 i, j; UINT8 j;
P_SetScale(mo, 2*mapobjectscale); P_SetScale(mo, 2*mapobjectscale);
mo->destscale = 2*mapobjectscale; mo->destscale = 2*mapobjectscale;
@ -136,7 +151,7 @@ void Obj_DLZSeasawSpawn(mobj_t *mo)
// center pole: // center pole:
pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK); pole = P_SpawnMobj(mo->x, mo->y, mo->z, MT_THOK);
pole->tics = -1; pole->tics = -1;
pole->sprite = SPR_DLZS; pole->sprite = SPR_GPPS;
pole->frame = 0; pole->frame = 0;
P_SetTarget(&pole->target, mo); P_SetTarget(&pole->target, mo);
P_SetTarget(&mo->tracer, pole); P_SetTarget(&mo->tracer, pole);
@ -144,62 +159,72 @@ void Obj_DLZSeasawSpawn(mobj_t *mo)
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
pole->eflags |= MFE_VERTICALFLIP; pole->eflags |= MFE_VERTICALFLIP;
int frame_lookup[4] = {0, 3, 1, 3}; // A D B D
// spawn visuals / hitboxes. // 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. vis->eflags |= MFE_VERTICALFLIP;
vis->flags2 |= MF2_OBJECTFLIP;
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. 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. h->eflags |= MFE_VERTICALFLIP;
h->flags2 |= MF2_OBJECTFLIP;
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;
} }
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. // 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; mo->extravalue1 = (INT32)mo->angle;
P_SetTarget(&mo->target, NULL); P_SetTarget(&mo->target, NULL);
Obj_DLZSeasawUpdate(mo, false); Obj_GPZSeasawUpdate(mo, false);
} }
// main seasaw thinker. // main seasaw thinker.
void Obj_DLZSeasawThink(mobj_t *mo) void Obj_GPZSeasawThink(mobj_t *mo)
{ {
boolean ghost = false; boolean ghost = false;
SINT8 rot = 1; SINT8 rot = 1;
@ -212,73 +237,44 @@ void Obj_DLZSeasawThink(mobj_t *mo)
if (!p) // untarget this instantly. if (!p) // untarget this instantly.
{ {
Obj_DLZSeasawReset(mo); Obj_GPZSeasawReset(mo);
return; return;
} }
if (!mo->extravalue2) if (!mo->extravalue2)
rot = -1; rot = -1;
// first half of the animation... INT32 angleadd = ANG1*max(4, (3*mo->movefactor/4)/(mapobjectscale*2)) * rot;
if (!p->seasawdir)
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) angle_t thrust_angle = mo->threshold ? mo->angle + ANGLE_180 : mo->angle;
angleadd /= max(1, (p->seasawangleadd - 160)/8); 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->seasawangleadd = 0;
p->seasawangle += angleadd; p->seasawangle = 0;
p->seasawmoreangle = 0;
p->seasaw = false;
p->seasawangleadd += max(4, (mo->movefactor/3)/mapobjectscale); Obj_GPZSeasawUpdate(mo, true);
P_SetPlayerAngle(p, (angle_t)(p->seasawangle + ANGLE_90*rot)); return;
//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 // update the player
px = mo->x + p->seasawdist*FINECOSINE((angle_t)p->seasawangle>>ANGLETOFINESHIFT); 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); P_MoveOrigin(t, px, py, mo->z + mapobjectscale*8);
} }
else else
Obj_DLZSeasawReset(mo); Obj_GPZSeasawReset(mo);
// finally, update the visuals. // 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... // 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. // to use in mobjcollide and movemobjcollide just like the lua, woo.
// mo is the player's mo, mo2 is the seasaw hitbox. // 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; player_t *p = mo->player;
INT32 momangle; INT32 momangle;
boolean invert = false;
// cooldown / respawning // cooldown / respawning
if (p->seasawcooldown || p->respawn.timer) 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))); //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. // this depends on the side we hit the thing from.
if (abs(((momangle - angtoint(mo2->target->angle) +180) % 360) - 180) > 60) mo2->target->threshold = (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->movefactor = p->speed; // keep the speed the player was going at.
mo2->target->extravalue2 = mo2->extravalue1; // which side of the pole are we on? mo2->target->extravalue2 = side ^ mo2->target->threshold; // 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); P_SetTarget(&mo2->target->target, mo);
mo2->target->cvmem = 0; mo2->target->cvmem = 0;
// set player vars now: // 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->seasawdist = (128 * mapobjectscale) / FRACUNIT;
p->seasawangle = (INT32)R_PointToAngle2(mo2->target->x, mo2->target->y, mo->x, mo->y); // angle from the center to us p->seasawangle = mo2->target->angle + (side ? ANGLE_270 : ANGLE_90);
p->seasawangleadd = 0; p->seasawangleadd = 0;
p->seasawdir = false; p->seasawdir = false;
p->seasaw = true; p->seasaw = true;
p->pflags |= PF_STASIS; p->pflags |= PF_STASIS;
p->seasawcooldown = TICRATE/2; p->seasawcooldown = TICRATE/2;
S_StartSound(mo, sfx_s3k88); S_StartSound(mo, sfx_s3k3c);
} }

View file

@ -724,6 +724,14 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
return BMIT_CONTINUE; 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 (thing->type == MT_DLZ_HOVER)
{ {
if (tm.thing->type == MT_PLAYER) if (tm.thing->type == MT_PLAYER)

View file

@ -10137,10 +10137,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
break; break;
case MT_DLZ_SEASAW_SPAWN:
Obj_DLZSeasawThink(mobj);
break;
case MT_DLZ_SUCKEDRING: case MT_DLZ_SUCKEDRING:
Obj_DLZSuckedRingThink(mobj); Obj_DLZSuckedRingThink(mobj);
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
@ -10177,6 +10173,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
} }
break; break;
case MT_DLZ_SEASAW_SPAWN:
Obj_DLZSeasawThink(mobj);
break;
case MT_GPZ_SEASAW_SPAWN:
Obj_GPZSeasawThink(mobj);
break;
case MT_BALLSWITCH_BALL: case MT_BALLSWITCH_BALL:
{ {
Obj_BallSwitchThink(mobj); 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: case MT_RIDEROIDNODE:
Obj_RideroidNodeSpawn(mobj); Obj_RideroidNodeSpawn(mobj);
break; break;
case MT_DLZ_SEASAW_SPAWN:
Obj_DLZSeasawSpawn(mobj);
break;
case MT_DLZ_HOVER: case MT_DLZ_HOVER:
Obj_DLZHoverSpawn(mobj); Obj_DLZHoverSpawn(mobj);
break; 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: case MT_BLENDEYE_PUYO_DUST:
mobj->sprite = mobj->movedir = P_RandomRange(PR_DECORATION, SPR_PUYA, SPR_PUYE); mobj->sprite = mobj->movedir = P_RandomRange(PR_DECORATION, SPR_PUYA, SPR_PUYE);
break; break;
case MT_DLZ_SEASAW_SPAWN:
Obj_DLZSeasawSpawn(mobj);
break;
case MT_GPZ_SEASAW_SPAWN:
Obj_GPZSeasawSpawn(mobj);
break;
default: default:
break; break;
} }