From 32607d61957dd4664c23e8aefafea28c0446aeb6 Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 23 Jan 2020 01:02:44 +0800 Subject: [PATCH 01/42] Reduce severity of glide landing & move skid dust to separate function --- src/info.c | 2 +- src/p_user.c | 74 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/info.c b/src/info.c index de6ff475c..5d403fa81 100644 --- a/src/info.c +++ b/src/info.c @@ -720,7 +720,7 @@ state_t states[NUMSTATES] = // CA_GLIDEANDCLIMB {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE - {SPR_PLAY, SPR2_LAND, 9, {NULL}, 0, 0, S_PLAY_STND}, // S_PLAY_GLIDE_LANDING + {SPR_PLAY, SPR2_LAND, 7, {NULL}, 0, 0, S_PLAY_STND}, // S_PLAY_GLIDE_LANDING {SPR_PLAY, SPR2_CLNG|FF_ANIMATE, -1, {NULL}, 0, 4, S_NULL}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB diff --git a/src/p_user.c b/src/p_user.c index a1df8a58b..9950cdf91 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2329,8 +2329,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); S_StartSound(player->mo, sfx_s3k4c); player->pflags |= PF_STASIS; - player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy; + if (player->speed > FixedMul(player->runspeed, player->mo->scale)) + player->skidtime += player->mo->tics; + player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; } } else if (player->charability2 == CA2_MELEE @@ -2380,6 +2382,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) } } } + else if (player->charability == CA_GLIDEANDCLIMB && (player->mo->state-states == S_PLAY_GLIDE_LANDING)) + ; else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) ; else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH) @@ -7852,6 +7856,36 @@ void P_ElementalFire(player_t *player, boolean cropcircle) } } +// +// P_SpawnSkidDust +// +// Spawns spindash dust randomly around the mobj using its radius as a bound +// +static void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) +{ + mobj_t *mo = player->mo; + mobj_t *particle; + + radius >>= FRACBITS; + if (radius) + particle = P_SpawnMobjFromMobj(mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST); + else + particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST); + particle->tics = 10; + + particle->destscale = (2*mo->scale)/3; + P_SetScale(particle, particle->destscale); + P_SetObjectMomZ(particle, FRACUNIT, false); + + if (mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version + P_SetMobjState(particle, S_SPINDUST_BUBBLE1); + else if (player->powers[pw_shield] == SH_ELEMENTAL) + P_SetMobjState(particle, S_SPINDUST_FIRE1); + + if (sound) + S_StartSound(mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx. +} + static void P_SkidStuff(player_t *player) { fixed_t pmx = player->rmomx + player->cmomx; @@ -7874,8 +7908,10 @@ static void P_SkidStuff(player_t *player) P_ResetPlayer(player); P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); player->pflags |= PF_STASIS; - player->mo->momx = ((player->mo->momx - player->cmomx)/3) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy)/3) + player->cmomy; + if (player->speed > FixedMul(player->runspeed, player->mo->scale)) + player->skidtime += player->mo->tics; + player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; } // Didn't stop yet? Skid FOREVER! else if (player->skidtime == 1) @@ -7883,20 +7919,7 @@ static void P_SkidStuff(player_t *player) // Spawn a particle every 3 tics. else if (!(player->skidtime % 3)) { - fixed_t radius = player->mo->radius >> FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(player->mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST); - particle->tics = 10; - - particle->destscale = (2*player->mo->scale)/3; - P_SetScale(particle, particle->destscale); - P_SetObjectMomZ(particle, FRACUNIT, false); - - if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version - P_SetMobjState(particle, S_SPINDUST_BUBBLE1); - else if (player->powers[pw_shield] == SH_ELEMENTAL) - P_SetMobjState(particle, S_SPINDUST_FIRE1); - - S_StartSound(player->mo, sfx_s3k7e); // the proper "Knuckles eats dirt" sfx. + P_SpawnSkidDust(player, player->mo->radius, true); } } // Skidding! @@ -7907,17 +7930,10 @@ static void P_SkidStuff(player_t *player) // Spawn a particle every 3 tics. if (!(player->skidtime % 3)) { - mobj_t *particle = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_SPINDUST); - particle->tics = 10; - - particle->destscale = (2*player->mo->scale)/3; - P_SetScale(particle, particle->destscale); - P_SetObjectMomZ(particle, FRACUNIT, false); - - if (player->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) // overrides fire version - P_SetMobjState(particle, S_SPINDUST_BUBBLE1); - else if (player->powers[pw_shield] == SH_ELEMENTAL) - P_SetMobjState(particle, S_SPINDUST_FIRE1); + if (player->mo->state-states == S_PLAY_GLIDE_LANDING) + P_SpawnSkidDust(player, player->mo->radius, true); + else + P_SpawnSkidDust(player, 0, false); } } else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame From 652a1984fe21d6416b33e8eda79820e1afc5f800 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 26 Jan 2020 03:44:10 +0800 Subject: [PATCH 02/42] Fix P_SpawnSkidDust description --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 9950cdf91..ba38e190d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7859,7 +7859,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) // // P_SpawnSkidDust // -// Spawns spindash dust randomly around the mobj using its radius as a bound +// Spawns spindash dust randomly around the player within a certain radius. // static void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) { From b6106ca8c5ef00317ba6d0fa1245a80653c82aae Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 26 Jan 2020 04:33:41 +0800 Subject: [PATCH 03/42] Don't spawn glide dust for SF_NOSKID characters --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index ba38e190d..fcc508688 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7917,7 +7917,7 @@ static void P_SkidStuff(player_t *player) else if (player->skidtime == 1) player->skidtime = 3*TICRATE+1; // Spawn a particle every 3 tics. - else if (!(player->skidtime % 3)) + else if (!(player->skidtime % 3) && !(player->charflags & SF_NOSKID)) { P_SpawnSkidDust(player, player->mo->radius, true); } From 305559b3f4220a7971026154f25e2cb79021bc55 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 2 Feb 2020 23:07:45 +0800 Subject: [PATCH 04/42] Move climbing checks to a separate function --- src/p_local.h | 1 + src/p_map.c | 229 +---------------------------------------------- src/p_user.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+), 228 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index a5f3d313c..a029b67b6 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -168,6 +168,7 @@ boolean P_AutoPause(void); void P_DoJumpShield(player_t *player); void P_DoBubbleBounce(player_t *player); +boolean P_TryClimb(player_t *player, line_t *line); void P_DoAbilityBounce(player_t *player, boolean changemomz); void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type); void P_BlackOw(player_t *player); diff --git a/src/p_map.c b/src/p_map.c index 40fee7b46..2314b7964 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3262,129 +3262,6 @@ isblocking: return false; // stop } -// -// P_IsClimbingValid -// -// Unlike P_DoClimbing, don't use when up against a one-sided linedef. -// -static boolean P_IsClimbingValid(player_t *player, angle_t angle) -{ - fixed_t platx, platy; - subsector_t *glidesector; - fixed_t floorz, ceilingz; - - platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - -#ifdef ESLOPE - floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; - ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; -#else - floorz = glidesector->sector->floorheight; - ceilingz = glidesector->sector->ceilingheight; -#endif - - if (glidesector->sector != player->mo->subsector->sector) - { - boolean floorclimb = false; - fixed_t topheight, bottomheight; - - if (glidesector->sector->ffloors) - { - ffloor_t *rover; - for (rover = glidesector->sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); -#endif - - floorclimb = true; - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) - { - floorclimb = true; - } - if (topheight < player->mo->z) // Waaaay below the ledge. - { - floorclimb = false; - } - if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - else - { - if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) - { - floorclimb = true; - } - if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. - { - floorclimb = false; - } - if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - - if (floorclimb) - break; - } - } - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((floorz <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) - floorclimb = true; - - if ((floorz > player->mo->z) - && glidesector->sector->floorpic == skyflatnum) - return false; - - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) - || (player->mo->z + player->mo->height <= floorz)) - floorclimb = true; - } - else - { - if ((ceilingz >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= ceilingz)) - floorclimb = true; - - if ((ceilingz < player->mo->z+player->mo->height) - && glidesector->sector->ceilingpic == skyflatnum) - return false; - - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) - || (player->mo->z >= ceilingz)) - floorclimb = true; - } - - if (!floorclimb) - return false; - - return true; - } - - return false; -} - // // PTR_SlideTraverse // @@ -3438,111 +3315,7 @@ isblocking: P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) - { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) - { - for (rover = checksector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); -#endif - - if (topheight < slidemo->z) - continue; - - if (bottomheight > slidemo->z + slidemo->height) - continue; - - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) - { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } - - break; - } - } - - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) - { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - - if (whichside) // on second side? - climbline += ANGLE_180; - - climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - - canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); - - if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) - || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) - && canclimb) - { - slidemo->angle = climbangle; - /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - }*/ - - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; - - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; - - if (fofline) - whichside = 0; - - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } - - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); - } - } - } + P_TryClimb(slidemo->player, li); if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { diff --git a/src/p_user.c b/src/p_user.c index 898286490..f029f7f72 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4907,6 +4907,246 @@ void P_DoBubbleBounce(player_t *player) player->mo->momz = FixedMul(player->mo->momz, 5*FRACUNIT/4); } +// +// P_IsClimbingValid +// +// Unlike P_DoClimbing, don't use when up against a one-sided linedef. +// +static boolean P_IsClimbingValid(player_t *player, angle_t angle) +{ + fixed_t platx, platy; + subsector_t *glidesector; + fixed_t floorz, ceilingz; + + platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); + + glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); + +#ifdef ESLOPE + floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; + ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; +#else + floorz = glidesector->sector->floorheight; + ceilingz = glidesector->sector->ceilingheight; +#endif + + if (glidesector->sector != player->mo->subsector->sector) + { + boolean floorclimb = false; + fixed_t topheight, bottomheight; + + if (glidesector->sector->ffloors) + { + ffloor_t *rover; + for (rover = glidesector->sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) + continue; + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); +#endif + + floorclimb = true; + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) + { + floorclimb = true; + } + if (topheight < player->mo->z) // Waaaay below the ledge. + { + floorclimb = false; + } + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) + { + floorclimb = false; + } + } + else + { + if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) + { + floorclimb = true; + } + if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. + { + floorclimb = false; + } + if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) + { + floorclimb = false; + } + } + + if (floorclimb) + break; + } + } + + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((floorz <= player->mo->z + player->mo->height) + && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) + floorclimb = true; + + if ((floorz > player->mo->z) + && glidesector->sector->floorpic == skyflatnum) + return false; + + if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) + || (player->mo->z + player->mo->height <= floorz)) + floorclimb = true; + } + else + { + if ((ceilingz >= player->mo->z) + && ((player->mo->z - player->mo->momz) >= ceilingz)) + floorclimb = true; + + if ((ceilingz < player->mo->z+player->mo->height) + && glidesector->sector->ceilingpic == skyflatnum) + return false; + + if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < floorz) + || (player->mo->z >= ceilingz)) + floorclimb = true; + } + + if (!floorclimb) + return false; + + return true; + } + + return false; +} + +// P_TryClimb +// +// Attempts to climb a line from the player's current position +// Returns whether or not the line was climbed +// +boolean P_TryClimb(player_t *player, line_t *line) +{ + if (player && (player->pflags & PF_GLIDING || player->climbing) + && player->charability == CA_GLIDEANDCLIMB) + { + mobj_t *mo = player->mo; + line_t *checkline = line; + sector_t *checksector; + ffloor_t *rover; + fixed_t topheight, bottomheight; + boolean fofline = false; + INT32 side = P_PointOnLineSide(mo->x, mo->y, line); + + if (!side && line->backsector) + checksector = line->backsector; + else + checksector = line->frontsector; + + if (checksector->ffloors) + { + for (rover = checksector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) + continue; + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mo->x, mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mo->x, mo->y); +#endif + + if (topheight < mo->z) + continue; + + if (bottomheight > mo->z + mo->height) + continue; + + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? + if (rover->master->flags & ML_TFERLINE) + { + size_t linenum = line-checksector->lines[0]; + checkline = rover->master->frontsector->lines[0] + linenum; + fofline = true; + } + + break; + } + } + + // see about climbing on the wall + if (!(checkline->flags & ML_NOCLIMB) && checkline->special != HORIZONSPECIAL) + { + boolean canclimb; + angle_t climbangle, climbline; + INT32 whichside = P_PointOnLineSide(mo->x, mo->y, line); + + climbangle = climbline = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y); + + if (whichside) // on second side? + climbline += ANGLE_180; + + climbangle += (ANGLE_90 * (whichside ? -1 : 1)); + + canclimb = (line->backsector ? P_IsClimbingValid(player, climbangle) : true); + + if (((!player->climbing && abs((signed)(mo->angle - ANGLE_90 - climbline)) < ANGLE_45) + || (player->climbing == 1 && abs((signed)(mo->angle - climbline)) < ANGLE_135)) + && canclimb) + { + mo->angle = climbangle; + /*if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) + { + if (player == &players[consoleplayer]) + localangle = mo->angle; + else if (player == &players[secondarydisplayplayer]) + localangle2 = mo->angle; + }*/ + + if (!player->climbing) + { + S_StartSound(player->mo, sfx_s3k4a); + player->climbing = 5; + } + + player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); + player->glidetime = 0; + player->secondjump = 0; + + if (player->climbing > 1) + mo->momz = mo->momx = mo->momy = 0; + + if (fofline) + whichside = 0; + + if (!whichside) + { + player->lastsidehit = checkline->sidenum[whichside]; + player->lastlinehit = (INT16)(checkline - lines); + } + + P_Thrust(mo, mo->angle, FixedMul(5*FRACUNIT, mo->scale)); + return true; + } + } + } + return false; +} + // // P_DoAbilityBounce // From 45173775528b46a66e7fb9f8b7354becddbbfadd Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 23 Feb 2020 15:38:11 +0800 Subject: [PATCH 05/42] Start CA_GLIDEANDCLIMB swimming functionality --- src/p_mobj.c | 9 +++++++-- src/p_user.c | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f3f0b9ab0..d9d0f2b56 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -215,10 +215,15 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) return P_SetPlayerMobjState(mobj, S_PLAY_FALL); // Catch swimming versus flying - if (state == S_PLAY_FLY && player->mo->eflags & MFE_UNDERWATER) + if ((state == S_PLAY_FLY || state == S_PLAY_GLIDE) && player->mo->eflags & MFE_UNDERWATER && !player->skidtime) return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) - return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); + { + if (player->charability == CA_GLIDEANDCLIMB) + return P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); + else + return P_SetPlayerMobjState(player->mo, S_PLAY_FLY); + } // Catch SF_NOSUPERSPIN jumps for Supers if (player->powers[pw_super] && (player->charflags & SF_NOSUPERSPIN)) diff --git a/src/p_user.c b/src/p_user.c index e2a7943f1..a01267b73 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2344,6 +2344,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (dorollstuff) { player->skidtime = TICRATE; + P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); player->mo->tics = -1; } else if (!player->skidtime) @@ -8583,6 +8584,32 @@ static void P_MovePlayer(player_t *player) if (!player->skidtime) // TODO: make sure this works in 2D! { + /*angle_t anglediff = angle - moveangle; + fixed_t scale = mo->scale; + fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); // mamgic number BAD but this feels right + fixed_t speed = FixedHypot(momx, momy); + fixed_t minspeed; + + if (anglediff > ANGLE_180) + anglediff = InvAngle(InvAngle(anglediff) >> 4); + else + anglediff = anglediff >> 4; + + if (mo->eflags & MFE_UNDERWATER) + minspeed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); + else + minspeed = FixedMul(glidespeed + player->glidetime*1500, scale); + + if (speed < minspeed) + { + momx += P_ReturnThrustX(mo, angle, FixedMul(accelfactor, scale)); + momy += P_ReturnThrustY(mo, angle, FixedMul(accelfactor, scale)); + speed = FixedHypot(momx, momy); // recalculate speed + } + + mo->momx = P_ReturnThrustX(mo, moveangle + anglediff, speed) + player->cmomx; + mo->momy = P_ReturnThrustY(mo, moveangle + anglediff, speed) + player->cmomy;*/ + fixed_t speed, scale = mo->scale; fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0); fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); // mamgic number BAD but this feels right From 38e2c999c56f1bdcd0d8926db3127b6758ef6787 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 14 Jun 2020 12:17:30 +0800 Subject: [PATCH 06/42] Platform fixes --- src/p_map.c | 8 ++++++++ src/p_user.c | 13 ++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 00b8761c8..6cc3b5ac0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2823,14 +2823,22 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) P_HandleSlopeLanding(thing, tmfloorslope); if (thing->momz <= 0) + { thing->standingslope = tmfloorslope; + if (thing->momz == 0 && thing->player && !startingonground) + P_PlayerHitFloor(thing->player, true); + } } else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) P_HandleSlopeLanding(thing, tmceilingslope); if (thing->momz >= 0) + { thing->standingslope = tmceilingslope; + if (thing->momz == 0 && thing->player && !startingonground) + P_PlayerHitFloor(thing->player, true); + } } } else // don't set standingslope if you're not going to clip against it diff --git a/src/p_user.c b/src/p_user.c index e07ddaec5..98542ad17 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2291,6 +2291,7 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) { boolean clipmomz; + CONS_Printf("Hit floor! %u\n", dorollstuff); I_Assert(player->mo != NULL); @@ -2301,7 +2302,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) { if (dorollstuff) { - if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) + if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && !(player->charability == CA_THOK && player->secondjump) + && (player->cmd.buttons & BT_USE) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale))) player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED; else if (!(player->pflags & PF_STARTDASH)) player->pflags &= ~PF_SPINNING; @@ -2402,7 +2404,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) ; else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2) ; - else if (player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH) + else if (dorollstuff && player->panim != PA_IDLE && player->panim != PA_WALK && player->panim != PA_RUN && player->panim != PA_DASH) { fixed_t runspd = FixedMul(player->runspeed, player->mo->scale); @@ -5146,6 +5148,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->mo->momz = 0; player->pflags &= ~(PF_STARTJUMP|PF_SPINNING); + player->secondjump = 1; } } break; @@ -5519,7 +5522,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) else potentialmomz = ((player->speed < 10*player->mo->scale) ? (player->speed - 10*player->mo->scale)/5 - : -1); // Should be 0, but made negative to ensure P_PlayerHitFloor runs upon touching ground + : 0); if (P_MobjFlip(player->mo)*player->mo->momz < potentialmomz) player->mo->momz = P_MobjFlip(player->mo)*potentialmomz; player->pflags &= ~PF_SPINNING; @@ -5531,7 +5534,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~PF_JUMPDOWN; // Repeat abilities, but not double jump! - if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP && player->charability != CA_AIRDRILL) + if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP && player->charability != CA_AIRDRILL && player->charability != CA_THOK) { if (player->charflags & SF_MULTIABILITY) { @@ -8411,7 +8414,7 @@ static void P_MovePlayer(player_t *player) // Also keep in mind the PF_JUMPED check. // If we lacked this, stepping up while jumping up would reset score. // (for instance, when climbing up off a wall.) - if ((onground || player->climbing) && !(player->pflags & PF_JUMPED) && player->powers[pw_invulnerability] <= 1) + if ((onground || player->climbing) && !(player->pflags & (PF_JUMPED|PF_BOUNCING)) && player->powers[pw_invulnerability] <= 1) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) From 29738fcdd007590bec7e19c2fd160081f96ea973 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 17 Jun 2020 01:46:36 +0800 Subject: [PATCH 07/42] Allow Fang to bounce on solid rising floors without taking damage/losing all scorechain --- src/p_map.c | 9 +++++++-- src/p_user.c | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 6cc3b5ac0..c9342a74f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2932,6 +2932,8 @@ static boolean P_ThingHeightClip(mobj_t *thing) ffloor_t *oldceilingrover = thing->ceilingrover; boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz); ffloor_t *rover = NULL; + boolean bouncing; + boolean hitfloor; if (thing->flags & MF_NOCLIPHEIGHT) return true; @@ -2954,7 +2956,9 @@ static boolean P_ThingHeightClip(mobj_t *thing) if (tmfloorz > oldfloorz+thing->height) return true; - if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved) + bouncing = thing->player && thing->state-states == S_PLAY_BOUNCE_LANDING && P_IsObjectOnGround(thing); + + if ((onfloor || bouncing) && !(thing->flags & MF_NOGRAVITY) && floormoved) { rover = (thing->eflags & MFE_VERTICALFLIP) ? oldceilingrover : oldfloorrover; @@ -2962,6 +2966,7 @@ static boolean P_ThingHeightClip(mobj_t *thing) // If ~FF_EXISTS, don't set mobj Z. if (!rover || ((rover->flags & FF_EXISTS) && (rover->flags & FF_SOLID))) { + hitfloor = bouncing; if (thing->eflags & MFE_VERTICALFLIP) thing->pmomz = thing->ceilingz - (thing->z + thing->height); else @@ -2986,7 +2991,7 @@ static boolean P_ThingHeightClip(mobj_t *thing) thing->z = thing->ceilingz - thing->height; } - if (P_MobjFlip(thing)*(thing->z - oldz) > 0 && thing->player) + if ((P_MobjFlip(thing)*(thing->z - oldz) > 0 || hitfloor) && thing->player) P_PlayerHitFloor(thing->player, !onfloor); // debug: be sure it falls to the floor diff --git a/src/p_user.c b/src/p_user.c index 98542ad17..20292dd08 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2319,6 +2319,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) if (player->scoreadd) player->scoreadd--; } + else + player->mo->z += P_MobjFlip(player->mo); clipmomz = false; } else @@ -8414,7 +8416,7 @@ static void P_MovePlayer(player_t *player) // Also keep in mind the PF_JUMPED check. // If we lacked this, stepping up while jumping up would reset score. // (for instance, when climbing up off a wall.) - if ((onground || player->climbing) && !(player->pflags & (PF_JUMPED|PF_BOUNCING)) && player->powers[pw_invulnerability] <= 1) + if ((onground || player->climbing) && !(player->pflags & PF_JUMPED) && player->powers[pw_invulnerability] <= 1) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) From edfd64877c085ec76dc197204c76de3957faa289 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 17 Jun 2020 04:53:42 +0800 Subject: [PATCH 08/42] Add SF_NOSUPERSPRITES --- src/d_player.h | 1 + src/dehacked.c | 1 + src/p_mobj.c | 2 +- src/st_stuff.c | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index fba2a6837..362d98639 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -49,6 +49,7 @@ typedef enum SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) + SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super // free up to and including 1<<31 } skinflags_t; diff --git a/src/dehacked.c b/src/dehacked.c index dba759894..af3f7528c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9619,6 +9619,7 @@ struct { {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, + {"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES}, // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, diff --git a/src/p_mobj.c b/src/p_mobj.c index f690ad894..288405d9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -394,7 +394,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (skin) { - spr2 = P_GetSkinSprite2(skin, (((player->powers[pw_super]) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); + spr2 = P_GetSkinSprite2(skin, (((player->powers[pw_super] && !(player->charflags & SF_NOSUPERSPRITES)) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); numframes = skin->sprites[spr2].numframes; } else diff --git a/src/st_stuff.c b/src/st_stuff.c index 086e80291..ce0480da3 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -821,7 +821,7 @@ static void ST_drawLivesArea(void) // skincolor face/super UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->mo->color, GTC_CACHE); patch_t *face = faceprefix[stplyr->skin]; - if (stplyr->powers[pw_super]) + if (stplyr->powers[pw_super] && !(stplyr->charflags & SF_NOSUPERSPRITES)) face = superprefix[stplyr->skin]; V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, face, colormap); From 7d92631d97faa1295ae6984fba1a943520ff797e Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 17 Jun 2020 05:27:42 +0800 Subject: [PATCH 09/42] Whoops, forgot hu_stuff.c --- src/hu_stuff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6f2319a50..ab02b48ce 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2240,7 +2240,7 @@ void HU_Erase(void) // IN-LEVEL MULTIPLAYER RANKINGS //====================================================================== -#define supercheckdef ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS1] || players[tab[i].num].mo->state >= &states[S_PLAY_SUPER_TRANS6])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER)) +#define supercheckdef (!(players[tab[i].num].charflags & SF_NOSUPERSPRITES) && ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS1] || players[tab[i].num].mo->state >= &states[S_PLAY_SUPER_TRANS6])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER))) #define greycheckdef (players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD || (G_IsSpecialStage(gamemap) && players[tab[i].num].exiting)) // @@ -2798,7 +2798,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor if (tab[i].color == 0) { colormap = colormaps; - if (players[tab[i].num].powers[pw_super]) + if (players[tab[i].num].powers[pw_super] && !(players[tab[i].num].charflags & SF_NOSUPERSPRITES)) V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT/4, 0, superprefix[players[tab[i].num].skin], 0); else { From 7b2e54b426b744db66bcefed5e4ff3d6049d63e3 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 00:52:24 +0800 Subject: [PATCH 10/42] Fix Dragonbomber z positioning --- src/info.c | 2 +- src/p_mobj.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index f0272fc79..123269656 100644 --- a/src/info.c +++ b/src/info.c @@ -5292,7 +5292,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_BOUNCE|MF_RUNSPAWNFUNC, // flags + MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME|MF_RUNSPAWNFUNC, // flags S_NULL // raisestate }, diff --git a/src/p_mobj.c b/src/p_mobj.c index f690ad894..44091d4ef 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9206,10 +9206,11 @@ static void P_DragonbomberThink(mobj_t *mobj) mobj->angle += DRAGONTURNSPEED; else { + boolean flip = mobj->spawnpoint->options & MTF_OBJECTFLIP; fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); fixed_t x = mobj->spawnpoint->x << FRACBITS; fixed_t y = mobj->spawnpoint->y << FRACBITS; - fixed_t z = mobj->spawnpoint->z << FRACBITS; + fixed_t z = (flip ? P_GetSectorCeilingZAt : P_GetSectorFloorZAt)(R_PointInSubsector(x, y)->sector, x, y) + (flip ? -1 : 1)*(mobj->spawnpoint->z << FRACBITS); angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle; if (diff > ANGLE_180) mobj->angle -= DRAGONTURNSPEED; From 682791a02499d31bbe8c99d5b8ce81b0b4382231 Mon Sep 17 00:00:00 2001 From: kaysrishaq <62462173+kaysrishaq@users.noreply.github.com> Date: Thu, 18 Jun 2020 17:09:29 -0400 Subject: [PATCH 11/42] brak missile fix, pw_ignorelatch, small Recycler fix --- src/d_player.h | 2 ++ src/dehacked.c | 4 ++- src/p_enemy.c | 7 ++++- src/p_inter.c | 85 ++++++++++++++++++++++++++++---------------------- src/p_map.c | 7 ++++- src/p_spec.c | 9 ++++++ src/p_user.c | 8 ++++- 7 files changed, 80 insertions(+), 42 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index fba2a6837..633f59bc3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -285,6 +285,8 @@ typedef enum pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch) + pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types + NUMPOWERS } powertype_t; diff --git a/src/dehacked.c b/src/dehacked.c index 61775bd56..94bb81614 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9312,7 +9312,9 @@ static const char *const POWERS_LIST[] = { //for dyes "DYE", - "JUSTLAUNCHED" + "JUSTLAUNCHED", + + "IGNORELATCH" }; static const char *const HUDITEMS_LIST[] = { diff --git a/src/p_enemy.c b/src/p_enemy.c index 578874574..3e80090f8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6946,7 +6946,9 @@ void A_RecyclePowers(mobj_t *actor) for (j = 0; j < NUMPOWERS; j++) { if (j == pw_flashing || j == pw_underwater || j == pw_spacetime || j == pw_carry - || j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super) + || j == pw_tailsfly || j == pw_extralife || j == pw_nocontrol || j == pw_super + || j == pw_pushing || j == pw_justsprung || j == pw_noautobrake || j == pw_justlaunched + || j == pw_ignorelatch) continue; players[recv_pl].powers[j] = powers[send_pl][j]; } @@ -13340,6 +13342,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) if (!player) return true; + if (player->powers[pw_carry] != CR_DUSTDEVIL && (player->powers[pw_ignorelatch] & (1<<15))) + return true; + if (abs(thing->x - dustdevil->x) > dustdevil->radius || abs(thing->y - dustdevil->y) > dustdevil->radius) return true; diff --git a/src/p_inter.c b/src/p_inter.c index 052ecc0da..629f976ff 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1468,7 +1468,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_BLACKEGGMAN_GOOPFIRE: - if (!player->powers[pw_flashing]) + if (!player->powers[pw_flashing] && !(player->powers[pw_ignorelatch] & (1<<15))) { toucher->momx = 0; toucher->momy = 0; @@ -1584,44 +1584,53 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_SMALLGRABCHAIN: case MT_BIGGRABCHAIN: - if (P_MobjFlip(toucher)*toucher->momz > 0 - || (player->powers[pw_carry])) - return; - - if (toucher->z > special->z + special->height/2) - return; - - if (toucher->z + toucher->height/2 < special->z) - return; - - if (player->powers[pw_flashing]) - return; - - if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) - { // I don't expect you to understand this, Mr Bond... - angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; - if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) - ang += ANGLE_180; - if (ang < ANGLE_180) - return; // I expect you to die. - } - - P_ResetPlayer(player); - P_SetTarget(&toucher->tracer, special); - - if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) { - player->powers[pw_carry] = CR_MACESPIN; - S_StartSound(toucher, sfx_spin); - P_SetPlayerMobjState(toucher, S_PLAY_ROLL); + boolean macespin = false; + if (P_MobjFlip(toucher)*toucher->momz > 0 + || (player->powers[pw_carry])) + return; + + if (toucher->z > special->z + special->height/2) + return; + + if (toucher->z + toucher->height/2 < special->z) + return; + + if (player->powers[pw_flashing]) + return; + + if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) + macespin = true; + + if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch])) + return; + + if (special->movefactor && special->tracer && special->tracer->angle != ANGLE_90 && special->tracer->angle != ANGLE_270) + { // I don't expect you to understand this, Mr Bond... + angle_t ang = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->tracer->angle; + if ((special->movefactor > 0) == (special->tracer->angle > ANGLE_90 && special->tracer->angle < ANGLE_270)) + ang += ANGLE_180; + if (ang < ANGLE_180) + return; // I expect you to die. + } + + P_ResetPlayer(player); + P_SetTarget(&toucher->tracer, special); + + if (macespin) + { + player->powers[pw_carry] = CR_MACESPIN; + S_StartSound(toucher, sfx_spin); + P_SetPlayerMobjState(toucher, S_PLAY_ROLL); + } + else + player->powers[pw_carry] = CR_GENERIC; + + // Can't jump first frame + player->pflags |= PF_JUMPSTASIS; + + return; } - else - player->powers[pw_carry] = CR_GENERIC; - - // Can't jump first frame - player->pflags |= PF_JUMPSTASIS; - - return; case MT_EGGMOBILE2_POGO: // sanity checks if (!special->target || !special->target->health) @@ -1711,7 +1720,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) + if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); diff --git a/src/p_map.c b/src/p_map.c index 00b8761c8..27ec85fe4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -527,6 +527,8 @@ static void P_DoPterabyteCarry(player_t *player, mobj_t *ptera) { if (player->powers[pw_carry] && player->powers[pw_carry] != CR_ROLLOUT) return; + if (player->powers[pw_ignorelatch] & (1<<15)) + return; if (ptera->extravalue1 != 1) return; // Not swooping if (ptera->target != player->mo) @@ -611,7 +613,8 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default && zdist > sonic->mo->height*2/3 - && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) + && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0 + && !(sonic->powers[pw_ignorelatch] & (1<<15))) { if (sonic-players == consoleplayer && botingame) CV_SetValue(&cv_analog[1], false); @@ -1002,6 +1005,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } if ((thing->flags & MF_PUSHABLE) // not carrying a player && (tmthing->player->powers[pw_carry] == CR_NONE) // player is not already riding something + && !(tmthing->player->powers[pw_ignorelatch] & (1<<15)) && ((tmthing->eflags & MFE_VERTICALFLIP) == (thing->eflags & MFE_VERTICALFLIP)) && (P_MobjFlip(tmthing)*tmthing->momz <= 0) && ((!(tmthing->eflags & MFE_VERTICALFLIP) && abs(thing->z + thing->height - tmthing->z) < (thing->height>>2)) @@ -1291,6 +1295,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && (thing->player->pflags & PF_JUMPED) && !thing->player->powers[pw_flashing] + && !thing->player->powers[pw_ignorelatch] && thing->tracer != tmthing && tmthing->target != thing) { diff --git a/src/p_spec.c b/src/p_spec.c index 7708f2f1e..25e23064b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4811,6 +4811,9 @@ DoneSection2: if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; + if (player->powers[pw_ignorelatch] & (1<<15)) + break; + // Find line #3 tagged to this sector lineindex = P_FindSpecialLineFromTag(3, sector->tag, -1); @@ -4873,6 +4876,9 @@ DoneSection2: if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE) break; + if (player->powers[pw_ignorelatch] & (1<<15)) + break; + // Find line #3 tagged to this sector lineindex = P_FindSpecialLineFromTag(3, sector->tag, -1); @@ -4983,6 +4989,9 @@ DoneSection2: if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) break; + if (player->powers[pw_ignorelatch] & (1<<15)) + break; + if (player->mo->momz > 0) break; diff --git a/src/p_user.c b/src/p_user.c index f21da1564..6fa33a3cd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4406,7 +4406,8 @@ void P_DoJump(player_t *player, boolean soundandstate) { player->mo->momz = 9*FRACUNIT; player->powers[pw_carry] = CR_NONE; - P_SetTarget(&player->mo->tracer->target, NULL); + if (!(player->mo->tracer->flags & MF_MISSILE)) // Missiles remember their owner! + P_SetTarget(&player->mo->tracer->target, NULL); P_SetTarget(&player->mo->tracer, NULL); } else if (player->powers[pw_carry] == CR_ROPEHANG) @@ -12089,6 +12090,11 @@ void P_PlayerThink(player_t *player) else player->powers[pw_nocontrol] = 0; + if (player->powers[pw_ignorelatch] & ((1<<15)-1) && player->powers[pw_ignorelatch] < UINT16_MAX) + player->powers[pw_ignorelatch]--; + else + player->powers[pw_ignorelatch] = 0; + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] From cad1f57b1e4d063e581853d40272f3272d39be34 Mon Sep 17 00:00:00 2001 From: kaysrishaq <62462173+kaysrishaq@users.noreply.github.com> Date: Sun, 7 Jun 2020 16:11:36 -0400 Subject: [PATCH 12/42] FF_HORIZONTALFLIP and mobj->mirrored (sprite enhancements) --- src/dehacked.c | 1 + src/hardware/hw_drv.h | 2 +- src/hardware/hw_main.c | 6 ++++++ src/hardware/hw_md2.c | 3 ++- src/hardware/r_opengl/r_opengl.c | 19 +++++++++++-------- src/lua_mobjlib.c | 8 ++++++++ src/p_mobj.h | 1 + src/p_pspr.h | 4 +++- src/p_saveg.c | 11 +++++++++-- src/r_things.c | 8 ++++++++ 10 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 61775bd56..98990b399 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9504,6 +9504,7 @@ struct { {"FF_GLOBALANIM",FF_GLOBALANIM}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_VERTICALFLIP",FF_VERTICALFLIP}, + {"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP}, {"FF_PAPERSPRITE",FF_PAPERSPRITE}, {"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSSHIFT",FF_TRANSSHIFT}, diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 2e4ea10cc..6f039cc3a 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -50,7 +50,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b89ffe9e6..bab5f625b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4724,6 +4724,8 @@ static void HWR_ProjectSprite(mobj_t *thing) unsigned rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + boolean mirrored = thing->mirrored; + boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); angle_t ang; INT32 heightsec, phs; @@ -4812,6 +4814,8 @@ static void HWR_ProjectSprite(mobj_t *thing) #endif ang = R_PointToAngle (thing->x, thing->y) - mobjangle; + if (mirrored) + ang = InvAngle(ang); if (sprframe->rotate == SRF_SINGLE) { @@ -4884,6 +4888,8 @@ static void HWR_ProjectSprite(mobj_t *thing) rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT)); } + flip = !flip != !hflip; + if (flip) { x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 76c7f89b4..42af89fd3 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1234,6 +1234,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) //mdlframe_t *next = NULL; const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); + const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; spriteinfo_t *sprinfo; @@ -1504,7 +1505,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) #endif HWD.pfnSetShader(4); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 41ec703bc..d3fc43e7b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2615,7 +2615,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2708,20 +2708,21 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglEnable(GL_NORMALIZE); #ifdef USE_FTRANSFORM_MIRROR - // flipped is if the object is flipped + // flipped is if the object is vertically flipped + // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically // pos->mirror is if the screen is flipped horizontally // XOR all the flips together to figure out what culling to use! { - boolean reversecull = (flipped ^ pos->flip ^ pos->mirror); + boolean reversecull = (flipped ^ hflipped ^ pos->flip ^ pos->mirror); if (reversecull) - pglCullFace(GL_FRONT); - else pglCullFace(GL_BACK); + else + pglCullFace(GL_FRONT); } #else // pos->flip is if the screen is flipped too - if (flipped != pos->flip) // If either are active, but not both, invert the model's culling + if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling { pglCullFace(GL_FRONT); } @@ -2736,6 +2737,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; + if (hflipped) + scalez = -scalez; #ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart @@ -2882,9 +2885,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); } // -----------------+ diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 4d0efa9e2..129339b96 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -86,6 +86,7 @@ enum mobj_e { mobj_cvmem, mobj_standingslope, mobj_colorized, + mobj_mirrored, mobj_shadowscale }; @@ -152,6 +153,7 @@ static const char *const mobj_opt[] = { "cvmem", "standingslope", "colorized", + "mirrored", "shadowscale", NULL}; @@ -385,6 +387,9 @@ static int mobj_get(lua_State *L) case mobj_colorized: lua_pushboolean(L, mo->colorized); break; + case mobj_mirrored: + lua_pushboolean(L, mo->mirrored); + break; case mobj_shadowscale: lua_pushfixed(L, mo->shadowscale); break; @@ -713,6 +718,9 @@ static int mobj_set(lua_State *L) case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; + case mobj_mirrored: + mo->mirrored = luaL_checkboolean(L, 3); + break; case mobj_shadowscale: mo->shadowscale = luaL_checkfixed(L, 3); break; diff --git a/src/p_mobj.h b/src/p_mobj.h index dae8c8a86..c94dbd650 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -373,6 +373,7 @@ typedef struct mobj_s struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) boolean colorized; // Whether the mobj uses the rainbow colormap + boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius // WARNING: New fields must be added separately to savegame and Lua. diff --git a/src/p_pspr.h b/src/p_pspr.h index 3c10e9be4..231262beb 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -64,8 +64,10 @@ #define FF_FULLBRIGHT 0x00100000 /// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity) #define FF_VERTICALFLIP 0x00200000 +/// \brief Frame flags: Flip sprite horizontally +#define FF_HORIZONTALFLIP 0x00400000 /// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION) -#define FF_PAPERSPRITE 0x00400000 +#define FF_PAPERSPRITE 0x00800000 /// \brief Frame flags - Animate: Simple stateless animation #define FF_ANIMATE 0x01000000 diff --git a/src/p_saveg.c b/src/p_saveg.c index b4d7ef838..c66d058f5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1294,8 +1294,9 @@ typedef enum MD2_CEILINGROVER = 1<<10, MD2_SLOPE = 1<<11, MD2_COLORIZED = 1<<12, - MD2_ROLLANGLE = 1<<13, - MD2_SHADOWSCALE = 1<<14, + MD2_MIRRORED = 1<<13, + MD2_ROLLANGLE = 1<<14, + MD2_SHADOWSCALE = 1<<15, } mobj_diff2_t; typedef enum @@ -1500,6 +1501,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SLOPE; if (mobj->colorized) diff2 |= MD2_COLORIZED; + if (mobj->mirrored) + diff2 |= MD2_MIRRORED; if (mobj->rollangle) diff2 |= MD2_ROLLANGLE; if (mobj->shadowscale) @@ -1638,6 +1641,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT16(save_p, mobj->standingslope->id); if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); + if (diff2 & MD2_MIRRORED) + WRITEUINT8(save_p, mobj->mirrored); if (diff2 & MD2_ROLLANGLE) WRITEANGLE(save_p, mobj->rollangle); if (diff2 & MD2_SHADOWSCALE) @@ -2641,6 +2646,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->standingslope = P_SlopeById(READUINT16(save_p)); if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); + if (diff2 & MD2_MIRRORED) + mobj->mirrored = READUINT8(save_p); if (diff2 & MD2_ROLLANGLE) mobj->rollangle = READANGLE(save_p); if (diff2 & MD2_SHADOWSCALE) diff --git a/src/r_things.c b/src/r_things.c index de5eb208f..d2647b811 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1367,6 +1367,8 @@ static void R_ProjectSprite(mobj_t *thing) size_t frame, rot; UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); + boolean mirrored = thing->mirrored; + boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); INT32 lindex; @@ -1477,7 +1479,11 @@ static void R_ProjectSprite(mobj_t *thing) #endif if (sprframe->rotate != SRF_SINGLE || papersprite) + { ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); + if (mirrored) + ang = InvAngle(ang); + } if (sprframe->rotate == SRF_SINGLE) { @@ -1537,6 +1543,8 @@ static void R_ProjectSprite(mobj_t *thing) } #endif + flip = !flip != !hflip; + // calculate edges of the shape if (flip) offset = spr_offset - spr_width; From c74a607c54c9b7a2f45bb12c11dda382311f4bc0 Mon Sep 17 00:00:00 2001 From: kaysrishaq <62462173+kaysrishaq@users.noreply.github.com> Date: Mon, 8 Jun 2020 06:30:01 -0400 Subject: [PATCH 13/42] Whoops, switched these for no reason --- src/hardware/r_opengl/r_opengl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d3fc43e7b..e5f6ff3cf 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2716,9 +2716,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { boolean reversecull = (flipped ^ hflipped ^ pos->flip ^ pos->mirror); if (reversecull) - pglCullFace(GL_BACK); - else pglCullFace(GL_FRONT); + else + pglCullFace(GL_BACK); } #else // pos->flip is if the screen is flipped too From bfa13827362d67220d864aa1ddef677867305603 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 8 Jun 2020 19:16:10 -0500 Subject: [PATCH 14/42] New Debris for CEZ3 --- src/dehacked.c | 10 ++++-- src/info.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/info.h | 9 ++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8450c16e6..77a539636 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -392,7 +392,7 @@ static void readPlayer(MYFILE *f, INT32 num) // It works down here, though. { INT32 numline = 0; - for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++) + for (i = 0; i < MAXLINELEN-1; i++) { if (numline < 20 && description[num].notes[i] == '\n') numline++; @@ -1174,7 +1174,7 @@ static void readgametype(MYFILE *f, char *gtname) // It works down here, though. { INT32 numline = 0; - for (i = 0; (size_t)i < sizeof(gtdescription)-1; i++) + for (i = 0; i < MAXLINELEN-1; i++) { if (numline < 20 && gtdescription[i] == '\n') numline++; @@ -8007,6 +8007,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_GFZDEBRIS", "S_BRICKDEBRIS", "S_WOODDEBRIS", + "S_COLOREDBRICKDEBRISA", + "S_COLOREDBRICKDEBRISB", + "S_COLOREDBRICKDEBRISC", #ifdef SEENAMES "S_NAMECHECK", @@ -8787,6 +8790,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_GFZDEBRIS", "MT_BRICKDEBRIS", "MT_WOODDEBRIS", + "MT_COLOREDBRICKDEBRISA", + "MT_COLOREDBRICKDEBRISB", + "MT_COLOREDBRICKDEBRISC", #ifdef SEENAMES "MT_NAMECHECK", diff --git a/src/info.c b/src/info.c index d443e035d..a0f91cbb4 100644 --- a/src/info.c +++ b/src/info.c @@ -509,6 +509,9 @@ char sprnames[NUMSPRITES + 1][5] = "GFZD", // GFZ debris "BRIC", // Bricks "WDDB", // Wood Debris + "BRIR", // CEZ3 colored bricks + "BRIB", // CEZ3 colored bricks + "BRIY", // CEZ3 colored bricks // Gravity Well Objects "GWLG", @@ -3910,6 +3913,9 @@ state_t states[NUMSTATES] = {SPR_GFZD, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_GFZDEBRIS {SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_BRICKDEBRIS {SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS + {SPR_BRIR, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISA + {SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISB + {SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISC #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -21586,6 +21592,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_COLOREDBRICKDEBRISA + -1, // doomednum + S_COLOREDBRICKDEBRISA, // spawnstate + 1, // 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 + 100, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_COLOREDBRICKDEBRISB + -1, // doomednum + S_COLOREDBRICKDEBRISB, // spawnstate + 1, // 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 + 100, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_COLOREDBRICKDEBRISC + -1, // doomednum + S_COLOREDBRICKDEBRISC, // spawnstate + 1, // 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 + 100, // mass + 0, // damage + sfx_crumbl, // activesound + MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_RUNSPAWNFUNC|MF_NOCLIPHEIGHT|MF_SCENERY, // flags + S_NULL // raisestate + }, + #ifdef SEENAMES { // MT_NAMECHECK -1, // doomednum diff --git a/src/info.h b/src/info.h index 79af9bbbb..67f4e1610 100644 --- a/src/info.h +++ b/src/info.h @@ -774,6 +774,9 @@ typedef enum sprite SPR_GFZD, // GFZ debris SPR_BRIC, // Bricks SPR_WDDB, // Wood Debris + SPR_BRIR, // CEZ3 colored bricks + SPR_BRIB, + SPR_BRIY, // Gravity Well Objects SPR_GWLG, @@ -3998,6 +4001,9 @@ typedef enum state S_GFZDEBRIS, S_BRICKDEBRIS, S_WOODDEBRIS, + S_COLOREDBRICKDEBRISA, // for CEZ3 + S_COLOREDBRICKDEBRISB, // for CEZ3 + S_COLOREDBRICKDEBRISC, // for CEZ3 #ifdef SEENAMES S_NAMECHECK, @@ -4798,6 +4804,9 @@ typedef enum mobj_type MT_GFZDEBRIS, MT_BRICKDEBRIS, MT_WOODDEBRIS, + MT_COLOREDBRICKDEBRISA, // for CEZ3 + MT_COLOREDBRICKDEBRISB, // for CEZ3 + MT_COLOREDBRICKDEBRISC, // for CEZ3 #ifdef SEENAMES MT_NAMECHECK, From fc68134938e4c0f3208769ac2c232db59cd17d24 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sat, 20 Jun 2020 02:04:18 -0500 Subject: [PATCH 15/42] Thanks for the feedback, I have fixed your issues. --- src/dehacked.c | 16 ++++++++-------- src/info.c | 18 +++++++++--------- src/info.h | 12 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 77a539636..610980812 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -392,7 +392,7 @@ static void readPlayer(MYFILE *f, INT32 num) // It works down here, though. { INT32 numline = 0; - for (i = 0; i < MAXLINELEN-1; i++) + for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++) { if (numline < 20 && description[num].notes[i] == '\n') numline++; @@ -1174,7 +1174,7 @@ static void readgametype(MYFILE *f, char *gtname) // It works down here, though. { INT32 numline = 0; - for (i = 0; i < MAXLINELEN-1; i++) + for (i = 0; (size_t)i < sizeof(gtdescription)-1; i++) { if (numline < 20 && gtdescription[i] == '\n') numline++; @@ -8007,9 +8007,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_GFZDEBRIS", "S_BRICKDEBRIS", "S_WOODDEBRIS", - "S_COLOREDBRICKDEBRISA", - "S_COLOREDBRICKDEBRISB", - "S_COLOREDBRICKDEBRISC", + "S_REDBRICKDEBRIS", + "S_BLUEBRICKDEBRIS", + "S_YELLOWBRICKDEBRIS", #ifdef SEENAMES "S_NAMECHECK", @@ -8790,9 +8790,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_GFZDEBRIS", "MT_BRICKDEBRIS", "MT_WOODDEBRIS", - "MT_COLOREDBRICKDEBRISA", - "MT_COLOREDBRICKDEBRISB", - "MT_COLOREDBRICKDEBRISC", + "MT_REDBRICKDEBRIS", + "MT_BLUEBRICKDEBRIS", + "MT_YELLOWBRICKDEBRIS", #ifdef SEENAMES "MT_NAMECHECK", diff --git a/src/info.c b/src/info.c index a0f91cbb4..ef31af9a6 100644 --- a/src/info.c +++ b/src/info.c @@ -3913,9 +3913,9 @@ state_t states[NUMSTATES] = {SPR_GFZD, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_GFZDEBRIS {SPR_BRIC, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_BRICKDEBRIS {SPR_WDDB, FF_ANIMATE, -1, {A_DebrisRandom}, 7, 2, S_NULL}, // S_WOODDEBRIS - {SPR_BRIR, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISA - {SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISB - {SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_COLOREDBRICKDEBRISC + {SPR_BRIR, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_REDBRICKDEBRIS + {SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_BLUEBRICKDEBRIS + {SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_YELLOWBRICKDEBRIS #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -21592,9 +21592,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_COLOREDBRICKDEBRISA + { // MT_REDBRICKDEBRIS -1, // doomednum - S_COLOREDBRICKDEBRISA, // spawnstate + S_REDBRICKDEBRIS, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -21619,9 +21619,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_COLOREDBRICKDEBRISB + { // MT_BLUEBRICKDEBRIS -1, // doomednum - S_COLOREDBRICKDEBRISB, // spawnstate + S_BLUEBRICKDEBRIS, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -21646,9 +21646,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_COLOREDBRICKDEBRISC + { // MT_YELLOWBRICKDEBRIS -1, // doomednum - S_COLOREDBRICKDEBRISC, // spawnstate + S_YELLOWBRICKDEBRIS, // spawnstate 1, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index 67f4e1610..fac690693 100644 --- a/src/info.h +++ b/src/info.h @@ -4001,9 +4001,9 @@ typedef enum state S_GFZDEBRIS, S_BRICKDEBRIS, S_WOODDEBRIS, - S_COLOREDBRICKDEBRISA, // for CEZ3 - S_COLOREDBRICKDEBRISB, // for CEZ3 - S_COLOREDBRICKDEBRISC, // for CEZ3 + S_REDBRICKDEBRIS, // for CEZ3 + S_BLUEBRICKDEBRIS, // for CEZ3 + S_YELLOWBRICKDEBRIS, // for CEZ3 #ifdef SEENAMES S_NAMECHECK, @@ -4804,9 +4804,9 @@ typedef enum mobj_type MT_GFZDEBRIS, MT_BRICKDEBRIS, MT_WOODDEBRIS, - MT_COLOREDBRICKDEBRISA, // for CEZ3 - MT_COLOREDBRICKDEBRISB, // for CEZ3 - MT_COLOREDBRICKDEBRISC, // for CEZ3 + MT_REDBRICKDEBRIS, // for CEZ3 + MT_BLUEBRICKDEBRIS, // for CEZ3 + MT_YELLOWBRICKDEBRIS, // for CEZ3 #ifdef SEENAMES MT_NAMECHECK, From ca7fc22388c2451c68f9fe780795de19a6b68a66 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sat, 20 Jun 2020 14:16:22 -0500 Subject: [PATCH 16/42] t_lspr --- src/hardware/hw_light.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 3d1316a2f..1f6b5525d 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -611,6 +611,9 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_GFZD &lspr[NOLIGHT], // SPR_BRIC &lspr[NOLIGHT], // SPR_WDDB + &lspr[NOLIGHT], // SPR_BRIR + &lspr[NOLIGHT], // SPR_BRIB + &lspr[NOLIGHT], // SPR_BRIY // Gravity Well Objects &lspr[NOLIGHT], // SPR_GWLG From 5655db11abc113b0e7075070116e5cfaebb4e44e Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 21 Jun 2020 09:30:55 +0200 Subject: [PATCH 17/42] Tweak display of hidden items in "1 Player" menu If an option in the "1 Player" menu is unavailable in an add-on, lower the above options to close the gap from the invisible option Also make Marathon Run display as question marks if locked And also change "sploadgame" to "spstartgame" --- src/m_menu.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 61b41d75b..e9c214019 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -761,14 +761,14 @@ static menuitem_t SP_MainMenu[] = {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, - {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 100}, + {IT_SECRET, NULL, "Marathon Run", M_Marathon, 100}, {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116} }; enum { - sploadgame, + spstartgame, sprecordattack, spnightsmode, spmarathon, @@ -8040,29 +8040,55 @@ static void M_SinglePlayerMenu(INT32 choice) { (void)choice; + levellistmode = LLM_RECORDATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; - else - SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; + else // If Record Attack is nonexistent in the current add-on... + { + SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Record Attack option... + SP_MainMenu[spstartgame].alphaKey += 8; // ...and lower Start Game by 8 pixels to close the gap + } + levellistmode = LLM_NIGHTSATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; - else - SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; + else // If NiGHTS Mode is nonexistent in the current add-on... + { + SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the NiGHTS Mode option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + } - SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED; // If the FIRST stage immediately leads to the ending, or itself (which gets converted to the title screen in G_DoCompleted for marathonmode only), there's no point in having this option on the menu. You should use Record Attack in that circumstance, although if marathonnext is set this behaviour can be overridden if you make some weird mod that requires multiple playthroughs of the same map in sequence and has some in-level mechanism to break the cycle. - if (!M_SecretUnlocked(SECRET_RECORDATTACK) // also if record attack is locked - || (mapheaderinfo[spmarathon_start-1] + if (mapheaderinfo[spmarathon_start-1] && !mapheaderinfo[spmarathon_start-1]->marathonnext && (mapheaderinfo[spmarathon_start-1]->nextlevel == spmarathon_start - || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100))) - SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; - else - SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; + || mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100)) + { + SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED; // Hide and disable the Marathon Run option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + SP_MainMenu[spnightsmode] .alphaKey += 8; + } + else if (M_SecretUnlocked(SECRET_RECORDATTACK)) // Otherwise, if Marathon Run is allowed and Record Attack is unlocked... + SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; // ...unlock Marathon Run! + + + if (!tutorialmap) // If there's no tutorial available in the current add-on... + { + SP_MainMenu[sptutorial].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Tutorial option... + // ...and lower the above options' display positions by 8 pixels to close the gap + SP_MainMenu[spstartgame] .alphaKey += 8; + SP_MainMenu[sprecordattack].alphaKey += 8; + SP_MainMenu[spnightsmode] .alphaKey += 8; + SP_MainMenu[spmarathon] .alphaKey += 8; + } + M_SetupNextMenu(&SP_MainDef); } From ae474b6945f3aae3f5d289207d5b655d011f0d03 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 21 Jun 2020 16:16:12 +0200 Subject: [PATCH 18/42] Fix re-opening 1 Player menu re-lowering options If an add-on disabled an option, re-opening the 1 Player menu multiple times would lower the above options multiple times Also fix Marathon Run and Tutorial being "perma-(un)lock"-able --- src/m_menu.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e9c214019..ed04d402b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -758,6 +758,7 @@ static menuitem_t SR_EmblemHintMenu[] = // Single Player Main static menuitem_t SP_MainMenu[] = { + // Note: If changing the positions here, also change them in M_SinglePlayerMenu() {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, @@ -8041,6 +8042,16 @@ static void M_SinglePlayerMenu(INT32 choice) (void)choice; + // Reset the item positions, to avoid them sinking farther down every time the menu is opened if one is unavailable + // Note that they're reset, not simply "not moved again", in case mid-game add-ons re-enable an option + SP_MainMenu[spstartgame] .alphaKey = 76; + SP_MainMenu[sprecordattack].alphaKey = 84; + SP_MainMenu[spnightsmode] .alphaKey = 92; + SP_MainMenu[spmarathon] .alphaKey = 100; + //SP_MainMenu[sptutorial] .alphaKey = 108; // Not needed + //SP_MainMenu[spstatistics].alphaKey = 116; // Not needed + + levellistmode = LLM_RECORDATTACK; if (M_GametypeHasLevels(-1)) SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; @@ -8075,11 +8086,13 @@ static void M_SinglePlayerMenu(INT32 choice) SP_MainMenu[sprecordattack].alphaKey += 8; SP_MainMenu[spnightsmode] .alphaKey += 8; } - else if (M_SecretUnlocked(SECRET_RECORDATTACK)) // Otherwise, if Marathon Run is allowed and Record Attack is unlocked... - SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED; // ...unlock Marathon Run! + else // Otherwise, if Marathon Run is allowed and Record Attack is unlocked, unlock Marathon Run! + SP_MainMenu[spmarathon].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; - if (!tutorialmap) // If there's no tutorial available in the current add-on... + if (tutorialmap) // If there's a tutorial available in the current add-on... + SP_MainMenu[sptutorial].status = IT_CALL | IT_STRING; // ...always unlock Tutorial + else // But if there's no tutorial available in the current add-on... { SP_MainMenu[sptutorial].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Tutorial option... // ...and lower the above options' display positions by 8 pixels to close the gap From d609cfc9e32b5dbf66cb790bfe4f691ad83b85f1 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 21 Jun 2020 03:06:42 -0500 Subject: [PATCH 19/42] Make it so Linedef type 422 instead sets `cusval` when the titlemap is in action. I have no idea why it wasn't like this before, but oh well. --- src/p_spec.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7708f2f1e..1f32c9eda 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2951,13 +2951,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // If titlemap, set the camera ref for title's thinker // This is not revoked until overwritten; awayviewtics is ignored if (titlemapinaction) - { titlemapcameraref = altview; - return; + else + { + P_SetTarget(&mo->player->awayviewmobj, altview); + mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; } - P_SetTarget(&mo->player->awayviewmobj, altview); - mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; if (line->flags & ML_NOCLIMB) // lets you specify a vertical angle { @@ -2971,10 +2971,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) aim *= (ANGLE_90>>8); aim /= 90; aim <<= 8; - mo->player->awayviewaiming = (angle_t)aim; + if (titlemapinaction) + titlemapcameraref->cusval = (angle_t)aim; + else + mo->player->awayviewaiming = (angle_t)aim; } else - mo->player->awayviewaiming = 0; // straight ahead + { + // straight ahead + if (titlemapinaction) + titlemapcameraref->cusval = 0; + else + mo->player->awayviewaiming = 0; + } } break; From 6fe087460642d243356349d8612daa5c722ec9fa Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 21 Jun 2020 23:21:42 -0500 Subject: [PATCH 20/42] Stop resetting cusval cause that's annoying --- src/p_spec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 1f32c9eda..e45220345 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2979,10 +2979,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else { // straight ahead - if (titlemapinaction) - titlemapcameraref->cusval = 0; - else + if (!titlemapinaction) mo->player->awayviewaiming = 0; + // don't do cusval cause that's annoying } } break; From f0787077e395920ec2461e99c6432b287ace7cc2 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 22 Jun 2020 04:14:42 -0500 Subject: [PATCH 21/42] More people ought to know what modulo is... Or modulous if your prefer. --- src/p_spec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index e45220345..6f5eba4c4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2964,10 +2964,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT32 aim; aim = sides[line->sidenum[0]].textureoffset>>FRACBITS; - while (aim < 0) - aim += 360; - while (aim >= 360) - aim -= 360; + aim = (aim + 360) % 360; aim *= (ANGLE_90>>8); aim /= 90; aim <<= 8; From dc2f689957fd461d423f39490ac8bdd7c67b0cf2 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 25 Jun 2020 00:38:07 -0500 Subject: [PATCH 22/42] Jet Jaw Sounds --- src/dehacked.c | 1 + src/info.c | 51 +++++++++++++++++++++++++------------------------- src/info.h | 1 + 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8450c16e6..7314f6456 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5195,6 +5195,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_JETJAW_CHOMP14", "S_JETJAW_CHOMP15", "S_JETJAW_CHOMP16", + "S_JETJAW_SOUND", // Snailer "S_SNAILER1", diff --git a/src/info.c b/src/info.c index d443e035d..bc5d218f0 100644 --- a/src/info.c +++ b/src/info.c @@ -965,30 +965,31 @@ state_t states[NUMSTATES] = {SPR_CSPR, 1, 1, {A_CrushclawAim}, 50, 20, S_CDIAG1}, // S_CDIAG8 // Jet Jaw - {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1 - {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM3}, // S_JETJAW_ROAM2 - {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM4}, // S_JETJAW_ROAM3 - {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM5}, // S_JETJAW_ROAM4 - {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM6}, // S_JETJAW_ROAM5 - {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM7}, // S_JETJAW_ROAM6 - {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM8}, // S_JETJAW_ROAM7 - {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM1}, // S_JETJAW_ROAM8 - {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP2}, // S_JETJAW_CHOMP1 - {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP3}, // S_JETJAW_CHOMP2 - {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP4}, // S_JETJAW_CHOMP3 - {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP5}, // S_JETJAW_CHOMP4 - {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP6}, // S_JETJAW_CHOMP5 - {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP7}, // S_JETJAW_CHOMP6 - {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP8}, // S_JETJAW_CHOMP7 - {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP9}, // S_JETJAW_CHOMP8 - {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP10}, // S_JETJAW_CHOMP9 - {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP11}, // S_JETJAW_CHOMP10 - {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP12}, // S_JETJAW_CHOMP11 - {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP13}, // S_JETJAW_CHOMP12 - {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP14}, // S_JETJAW_CHOMP13 - {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP15}, // S_JETJAW_CHOMP14 - {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP16}, // S_JETJAW_CHOMP15 - {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP1}, // S_JETJAW_CHOMP16 + {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM2}, // S_JETJAW_ROAM1 + {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM3}, // S_JETJAW_ROAM2 + {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM4}, // S_JETJAW_ROAM3 + {SPR_JJAW, 0, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM5}, // S_JETJAW_ROAM4 + {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM6}, // S_JETJAW_ROAM5 + {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM7}, // S_JETJAW_ROAM6 + {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM8}, // S_JETJAW_ROAM7 + {SPR_JJAW, 1, 1, {A_JetJawRoam}, 0, 0, S_JETJAW_ROAM1}, // S_JETJAW_ROAM8 + {SPR_JJAW, 0, 1, {A_DualAction}, S_JETJAW_CHOMP16, S_JETJAW_SOUND, S_JETJAW_CHOMP2}, // S_JETJAW_CHOMP1 + {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP3}, // S_JETJAW_CHOMP2 + {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP4}, // S_JETJAW_CHOMP3 + {SPR_JJAW, 0, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP5}, // S_JETJAW_CHOMP4 + {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP6}, // S_JETJAW_CHOMP5 + {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP7}, // S_JETJAW_CHOMP6 + {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP8}, // S_JETJAW_CHOMP7 + {SPR_JJAW, 1, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP9}, // S_JETJAW_CHOMP8 + {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP10}, // S_JETJAW_CHOMP9 + {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP11}, // S_JETJAW_CHOMP10 + {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP12}, // S_JETJAW_CHOMP11 + {SPR_JJAW, 2, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP13}, // S_JETJAW_CHOMP12 + {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP14}, // S_JETJAW_CHOMP13 + {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP15}, // S_JETJAW_CHOMP14 + {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP16}, // S_JETJAW_CHOMP15 + {SPR_JJAW, 3, 1, {A_JetJawChomp}, 0, 0, S_JETJAW_CHOMP1}, // S_JETJAW_CHOMP16 + {SPR_JJAW, 0, 1, {A_PlayAttackSound}, 0, 0, S_JETJAW_SOUND}, // S_JETJAW_SOUND // Snailer {SPR_SNLR, 0, 1, {A_SnailerThink}, 0, 0, S_SNAILER1}, // S_SNAILER1 @@ -4573,7 +4574,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_JETJAW_CHOMP1,// seestate sfx_None, // seesound 4*TICRATE, // reactiontime - sfx_None, // attacksound + sfx_s1ab, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound diff --git a/src/info.h b/src/info.h index 79af9bbbb..6b8c01266 100644 --- a/src/info.h +++ b/src/info.h @@ -1186,6 +1186,7 @@ typedef enum state S_JETJAW_CHOMP14, S_JETJAW_CHOMP15, S_JETJAW_CHOMP16, + S_JETJAW_SOUND, // Snailer S_SNAILER1, From fef15be0afedc46dc2b970add95b3f08f1b819b7 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 27 Jun 2020 10:56:15 -0500 Subject: [PATCH 23/42] Create a slightly more dynamic, optional frame delay system to show off your terrible hardware with --- src/d_netcmd.c | 1 + src/m_anigif.c | 27 ++++++++++++++++++++++++--- src/m_anigif.h | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b5ebad6d6..4f5c17c95 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -675,6 +675,7 @@ void D_RegisterClientCommands(void) // GIF variables CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_downscale); + CV_RegisterVar(&cv_gif_dynamicdelay); CV_RegisterVar(&cv_gif_localcolortable); #ifdef WALLSPLATS diff --git a/src/m_anigif.c b/src/m_anigif.c index 1b71a09bc..83bc3dddc 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -18,6 +18,7 @@ #include "z_zone.h" #include "v_video.h" #include "i_video.h" +#include "i_system.h" // I_GetTimeMicros #include "m_misc.h" #include "st_stuff.h" // st_palette @@ -30,11 +31,13 @@ consvar_t cv_gif_optimize = {"gif_optimize", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gif_dynamicdelay = {"gif_dynamicdelay", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gif_localcolortable = {"gif_localcolortable", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output +static boolean gif_dynamicdelay = false; // and messing something up // Palette handling static boolean gif_localcolortable = false; @@ -44,6 +47,7 @@ static RGBA_t *gif_framepalette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; +static UINT32 gif_prevframems = 0; static UINT8 gif_writeover = 0; @@ -588,11 +592,25 @@ static void GIF_framewrite(void) // screen regions are handled in GIF_lzw { - int d1 = (int)((100.0f/NEWTICRATE)*(gif_frames+1)); - int d2 = (int)((100.0f/NEWTICRATE)*(gif_frames)); - UINT16 delay = d1-d2; + UINT16 delay; INT32 startline; + if (gif_dynamicdelay) { + // golden's attempt at creating a "dynamic delay" + float delayf = ceil(100.0f/NEWTICRATE); + + delay = (UINT16)((I_GetTimeMicros() - gif_prevframems)/10/1000); + if (delay < (int)(delayf)) + delay = (int)(delayf); + } + else + { + // the original code + int d1 = (int)((100.0f/NEWTICRATE)*(gif_frames+1)); + int d2 = (int)((100.0f/NEWTICRATE)*(gif_frames)); + delay = d1-d2; + } + WRITEMEM(p, gifframe_gchead, 4); WRITEUINT16(p, delay); @@ -670,6 +688,7 @@ static void GIF_framewrite(void) } fwrite(gifframe_data, 1, (p - gifframe_data), gif_out); ++gif_frames; + gif_prevframems = I_GetTimeMicros(); } @@ -690,12 +709,14 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); + gif_dynamicdelay = (!!cv_gif_dynamicdelay.value); gif_localcolortable = (!!cv_gif_localcolortable.value); gif_colorprofile = (!!cv_screenshot_colorprofile.value); gif_headerpalette = GIF_getpalette(0); GIF_headwrite(); gif_frames = 0; + gif_prevframems = I_GetTimeMicros(); return 1; } diff --git a/src/m_anigif.h b/src/m_anigif.h index 4bb45b67d..abe05dd96 100644 --- a/src/m_anigif.h +++ b/src/m_anigif.h @@ -27,6 +27,6 @@ void GIF_frame(void); INT32 GIF_close(void); #endif -extern consvar_t cv_gif_optimize, cv_gif_downscale, cv_gif_localcolortable; +extern consvar_t cv_gif_optimize, cv_gif_downscale, cv_gif_dynamicdelay, cv_gif_localcolortable; #endif From 335fc0b3275fa0368489ebe0ff6231f7995ceed0 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 27 Jun 2020 14:30:41 -0700 Subject: [PATCH 24/42] Use levelflat->name instead of flatname --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 5027bab0c..12f12e27a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -575,9 +575,9 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize) strupr(levelflat->name); /* If we can't find a flat, try looking for a texture! */ - if (( flatnum = R_GetFlatNumForName(flatname) ) == LUMPERROR) + if (( flatnum = R_GetFlatNumForName(levelflat->name) ) == LUMPERROR) { - if (( texturenum = R_CheckTextureNumForName(flatname) ) == -1) + if (( texturenum = R_CheckTextureNumForName(levelflat->name) ) == -1) { // check for REDWALL if (( texturenum = R_CheckTextureNumForName("REDWALL") ) != -1) From 3f3ff0688ba18dcfb5e83a3b2f865380d384ac43 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 28 Jun 2020 16:59:36 -0400 Subject: [PATCH 25/42] Add support for saving/loading per-skin NiGHTS replays --- src/g_game.c | 6 +++--- src/m_menu.c | 37 ++++++++++++++++++++----------------- src/p_setup.c | 40 ++++++++++++++++++++++++++++++++++------ 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a927f8ef2..692dbf439 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -720,14 +720,14 @@ void G_SetNightsRecords(void) I_Error("Out of memory for replay filepath\n"); sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); - snprintf(lastdemo, 255, "%s-last.lmp", gpath); + snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); if (FIL_FileExists(lastdemo)) { UINT8 *buf; size_t len = FIL_ReadFile(lastdemo, &buf); - snprintf(bestdemo, 255, "%s-time-best.lmp", gpath); + snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);; if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) { // Better time, save this demo. if (FIL_FileExists(bestdemo)) @@ -736,7 +736,7 @@ void G_SetNightsRecords(void) CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); } - snprintf(bestdemo, 255, "%s-score-best.lmp", gpath); + snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) { // Better score, save this demo. if (FIL_FileExists(bestdemo)) diff --git a/src/m_menu.c b/src/m_menu.c index f684354a5..a470b4021 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2300,7 +2300,7 @@ void Nextmap_OnChange(void) SP_NightsAttackMenu[naghost].status = IT_DISABLED; // Check if file exists, if not, disable REPLAY option - sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name); for (i = 0; i < 4; i++) { SP_NightsReplayMenu[i].status = IT_DISABLED; SP_NightsGuestReplayMenu[i].status = IT_DISABLED; @@ -2320,7 +2320,7 @@ void Nextmap_OnChange(void) SP_NightsGuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; active = true; } - if (FIL_FileExists(va("%s-guest.lmp", tabase))) { + if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) { SP_NightsReplayMenu[3].status = IT_WHITESTRING|IT_CALL; SP_NightsGuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; active = true; @@ -10126,6 +10126,8 @@ static void M_NightsAttack(INT32 choice) // Player has selected the "START" from the nights attack screen static void M_ChooseNightsAttack(INT32 choice) { + char *gpath; + const size_t glen = strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char nameofdemo[256]; (void)choice; emeralds = 0; @@ -10136,14 +10138,18 @@ static void M_ChooseNightsAttack(INT32 choice) I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); - snprintf(nameofdemo, sizeof nameofdemo, "replay"PATHSEP"%s"PATHSEP"%s-last", timeattackfolder, G_BuildMapName(cv_nextmap.value)); + if ((gpath = malloc(glen)) == NULL) + I_Error("Out of memory for replay filepath\n"); + + sprintf(gpath,"replay"PATHSEP"%s"PATHSEP"%s", timeattackfolder, G_BuildMapName(cv_nextmap.value)); + snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-last", gpath, skins[cv_chooseskin.value-1].name); if (!cv_autorecord.value) remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo)); else G_RecordDemo(nameofdemo); - G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), 0, false, false); + G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), (UINT8)(cv_chooseskin.value-1), false, false); } // Player has selected the "START" from the time attack screen @@ -10220,11 +10226,10 @@ static void M_ReplayTimeAttack(INT32 choice) which = "last"; break; case 3: // guest - which = "guest"; - break; + G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + return; } - // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); + G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which)); } } @@ -10242,15 +10247,13 @@ static void M_EraseGuest(INT32 choice) M_StartMessage(M_GetText("Guest replay data erased.\n"),NULL,MM_NOTHING); } -static void M_OverwriteGuest(const char *which, boolean nights) +static void M_OverwriteGuest(const char *which) { char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); UINT8 *buf; size_t len; - if (!nights) - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which), &buf); - else - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which), &buf); + len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which), &buf); + if (!len) { return; } @@ -10271,25 +10274,25 @@ static void M_OverwriteGuest(const char *which, boolean nights) static void M_OverwriteGuest_Time(INT32 choice) { (void)choice; - M_OverwriteGuest("time-best", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("time-best"); } static void M_OverwriteGuest_Score(INT32 choice) { (void)choice; - M_OverwriteGuest("score-best", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("score-best"); } static void M_OverwriteGuest_Rings(INT32 choice) { (void)choice; - M_OverwriteGuest("rings-best", false); + M_OverwriteGuest("rings-best"); } static void M_OverwriteGuest_Last(INT32 choice) { (void)choice; - M_OverwriteGuest("last", currentMenu == &SP_NightsGuestReplayDef); + M_OverwriteGuest("last"); } static void M_SetGuestReplay(INT32 choice) diff --git a/src/p_setup.c b/src/p_setup.c index 5027bab0c..d088f3a20 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3157,6 +3157,7 @@ static void P_LoadNightsGhosts(void) { const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath = malloc(glen); + INT32 i; if (!gpath) return; @@ -3164,16 +3165,43 @@ static void P_LoadNightsGhosts(void) sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); // Best Score ghost - if (cv_ghost_bestscore.value && FIL_FileExists(va("%s-score-best.lmp", gpath))) - G_AddGhost(va("%s-score-best.lmp", gpath)); + if (cv_ghost_bestscore.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name)); + } + } // Best Time ghost - if (cv_ghost_besttime.value && FIL_FileExists(va("%s-time-best.lmp", gpath))) - G_AddGhost(va("%s-time-best.lmp", gpath)); + if (cv_ghost_besttime.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name)); + } + } // Last ghost - if (cv_ghost_last.value && FIL_FileExists(va("%s-last.lmp", gpath))) - G_AddGhost(va("%s-last.lmp", gpath)); + if (cv_ghost_last.value) + { + for (i = 0; i < numskins; ++i) + { + if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i) + continue; + + if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name))) + G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name)); + } + } // Guest ghost if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath))) From e6418952685ce1829ff1a7a512ed07ddc4fbdceb Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 29 Jun 2020 23:54:45 -0400 Subject: [PATCH 26/42] Address compat with old-style names --- src/m_menu.c | 41 ++++++++++++++++++++++++++++++++++++++++- src/m_menu.h | 3 +++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index a470b4021..490e2081b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2276,6 +2276,9 @@ void Nextmap_OnChange(void) { char *leveltitle; char tabase[256]; +#ifdef OLDNREPLAYNAME + char tabaseold[256]; +#endif short i; boolean active; @@ -2301,10 +2304,16 @@ void Nextmap_OnChange(void) // Check if file exists, if not, disable REPLAY option sprintf(tabase,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name); + +#ifdef OLDNREPLAYNAME + sprintf(tabaseold,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s",srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); +#endif + for (i = 0; i < 4; i++) { SP_NightsReplayMenu[i].status = IT_DISABLED; SP_NightsGuestReplayMenu[i].status = IT_DISABLED; } + if (FIL_FileExists(va("%s-score-best.lmp", tabase))) { SP_NightsReplayMenu[0].status = IT_WHITESTRING|IT_CALL; SP_NightsGuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; @@ -2325,11 +2334,32 @@ void Nextmap_OnChange(void) SP_NightsGuestReplayMenu[3].status = IT_WHITESTRING|IT_CALL; active = true; } + + // Old style name compatibility +#ifdef OLDNREPLAYNAME + if (FIL_FileExists(va("%s-score-best.lmp", tabaseold))) { + SP_NightsReplayMenu[0].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[0].status = IT_WHITESTRING|IT_CALL; + active = true; + } + if (FIL_FileExists(va("%s-time-best.lmp", tabaseold))) { + SP_NightsReplayMenu[1].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[1].status = IT_WHITESTRING|IT_CALL; + active = true; + } + if (FIL_FileExists(va("%s-last.lmp", tabaseold))) { + SP_NightsReplayMenu[2].status = IT_WHITESTRING|IT_CALL; + SP_NightsGuestReplayMenu[2].status = IT_WHITESTRING|IT_CALL; + active = true; + } +#endif + if (active) { SP_NightsAttackMenu[naguest].status = IT_WHITESTRING|IT_SUBMENU; SP_NightsAttackMenu[nareplay].status = IT_WHITESTRING|IT_SUBMENU; SP_NightsAttackMenu[naghost].status = IT_WHITESTRING|IT_SUBMENU; } + else if(itemOn == nareplay) // Reset lastOn so replay isn't still selected when not available. { currentMenu->lastOn = itemOn; @@ -10185,6 +10215,7 @@ static void M_ChooseTimeAttack(INT32 choice) static void M_ReplayTimeAttack(INT32 choice) { const char *which; + char *demoname; M_ClearMenus(true); modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows @@ -10229,7 +10260,15 @@ static void M_ReplayTimeAttack(INT32 choice) G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); return; } - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which)); + + demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); + +#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay, since the new style replay doesn't exist. + if (!FIL_FileExists(demoname)) + demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); +#endif + + G_DoPlayDemo(demoname); } } diff --git a/src/m_menu.h b/src/m_menu.h index 221f1fd3f..52bdb0dea 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -21,6 +21,9 @@ #include "r_skins.h" // for SKINNAMESIZE #include "f_finale.h" // for ttmode_enum +// Compatibility with old-style named NiGHTS replay files. +#define OLDNREPLAYNAME + // // MENUS // From 612386aef0783458ddeaa644487ff7c922a76d95 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 29 Jun 2020 23:57:39 -0400 Subject: [PATCH 27/42] Correct comment --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 490e2081b..a9bb1fda9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10263,7 +10263,7 @@ static void M_ReplayTimeAttack(INT32 choice) demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); -#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay, since the new style replay doesn't exist. +#ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay if a new style replay doesn't exist. if (!FIL_FileExists(demoname)) demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); #endif From 40e98e57123753230bd9035ad08507759884cf8c Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Tue, 30 Jun 2020 18:37:21 +0200 Subject: [PATCH 28/42] Fix crash when a polyobject rotates a non-player mobj --- src/p_polyobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 5bd963940..ccf8519f6 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1159,7 +1159,8 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; - P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); + if (mo->player) + P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta); } } } From fae583915a42dff159469ac44d7186e566b647d8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:04:46 -0700 Subject: [PATCH 29/42] Remove Producer role from the credits --- src/f_finale.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index a41005b43..24ace29d0 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1118,9 +1118,6 @@ static const char *credits[] = { "\1Sonic Robo Blast II", "\1Credits", "", - "\1Producer", - "Rob Tisdell", - "", "\1Game Design", "Ben \"Mystic\" Geyer", "\"SSNTails\"", From 99a9c935f915b3cc693565afeb2b319f1b60c98e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:23:26 -0700 Subject: [PATCH 30/42] Credits: add back fickle, add Chrispy and Hannu --- src/f_finale.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/f_finale.c b/src/f_finale.c index 24ace29d0..cd55ff42d 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1148,11 +1148,13 @@ static const char *credits[] = { "", "\1Programming", "\1Assistance", + "Colette \"fickleheart\" Bordelon", "\"chi.miru\"", // helped port slope drawing code from ZDoom "Andrew \"orospakr\" Clunis", "Sally \"TehRealSalt\" Cochenour", "Gregor \"Oogaland\" Dick", "Julio \"Chaos Zero 64\" Guir", + "\"Hannu_Hanhi\"", // For many OpenGL performance improvements! "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Lat'\"", // SRB2-CHAT, the chat window from Kart "Matthew \"Shuffle\" Marsalko", @@ -1171,6 +1173,7 @@ static const char *credits[] = { "\1Art", "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: "Ryan \"Blaze Hedgehog\" Bloom", + "\"ChrispyPixels\"", "Paul \"Boinciel\" Clempson", "Sally \"TehRealSalt\" Cochenour", "\"Dave Lite\"", @@ -1217,6 +1220,7 @@ static const char *credits[] = { "\"SSNTails\"", "", "\1Level Design", + "Colette \"fickleheart\" Bordelon", "Hank \"FuriousFox\" Brannock", "Matthew \"Fawfulfan\" Chapman", "Paul \"Boinciel\" Clempson", From e1996a437d6356de4901eb7758655a36c22879d9 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:28:59 -0700 Subject: [PATCH 31/42] Add "Discord Community Testers" to the Testing section --- src/f_finale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/f_finale.c b/src/f_finale.c index cd55ff42d..2ce8fd101 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1256,6 +1256,7 @@ static const char *credits[] = { "Johnny \"Sonikku\" Wallbank", "", "\1Testing", + "Discord Community Testers", "Hank \"FuriousFox\" Brannock", "Cody \"SRB2 Playah\" Koester", "Skye \"OmegaVelocity\" Meredith", From 2cbf7ac27d816288ba3df876cd123cee88ee2988 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jul 2020 16:35:38 -0700 Subject: [PATCH 32/42] Cheese mode activate! --- src/locale/en.po | 2 +- src/locale/srb2.pot | 2 +- src/m_cheat.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locale/en.po b/src/locale/en.po index 83e118772..30ebe4368 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -2068,7 +2068,7 @@ msgstr "" #: m_cheat.c:292 #, c-format -msgid "Sissy Mode %s\n" +msgid "Cheese Mode %s\n" msgstr "" #: m_cheat.c:315 m_cheat.c:349 m_cheat.c:514 m_cheat.c:538 m_cheat.c:557 diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index 087c8720c..960c36dbe 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -2145,7 +2145,7 @@ msgstr "" #: m_cheat.c:294 #, c-format -msgid "Sissy Mode %s\n" +msgid "Cheese Mode %s\n" msgstr "" #: m_cheat.c:314 diff --git a/src/m_cheat.c b/src/m_cheat.c index 9d904f52d..c42763afd 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -288,7 +288,7 @@ void Command_CheatGod_f(void) plyr = &players[consoleplayer]; plyr->pflags ^= PF_GODMODE; - CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); + CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); G_SetGameModified(multiplayer); } From 29dfa5f605e24baa4eff4bddbebe14d0e1851afb Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Wed, 1 Jul 2020 23:18:20 -0500 Subject: [PATCH 33/42] sound caption --- src/sounds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sounds.c b/src/sounds.c index 9894fd13e..092bda21f 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -330,7 +330,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s1a8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s1a9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s1aa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s1ab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"s1ab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Chomp"}, {"s1ac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s1ad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s1ae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, From 1cc2ab120d6ec58a023b799289f1ee0143e135a7 Mon Sep 17 00:00:00 2001 From: colette Date: Thu, 2 Jul 2020 23:17:33 -0400 Subject: [PATCH 34/42] "Legacy controls" was a mistake of a name --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index f684354a5..97d14ccf4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4404,7 +4404,7 @@ static void M_DrawGenericMenu(void) } } -const char *PlaystyleNames[4] = {"Legacy", "Standard", "Simple", "Old Analog??"}; +const char *PlaystyleNames[4] = {"Strafe", "Standard", "Simple", "Old Analog??"}; const char *PlaystyleDesc[4] = { // Legacy "The play style used for\n" From 8652bbc1a56c327eee13d8fbb61e6bbeba0bd5d9 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 4 Jul 2020 01:54:00 +0800 Subject: [PATCH 35/42] Knuckles changes: - Buffed crouch landing; lasts slightly shorter and cuts speed less - Support for swimming! Knuckles has slightly different glide controls when he has swim sprites underwater - Improved glide controls in 2D mode - Super Knuckles perks: land from a glide or latch onto a wall to generate a shockwave and damage nearby enemies - Refactored skid dust - Made super sparks use FF_FULLBRIGHT - Added P_SpawnSkidDust and P_Earthquake to Lua --- src/d_player.h | 1 + src/dehacked.c | 1 + src/info.c | 10 +- src/lua_baselib.c | 28 +++++ src/p_local.h | 2 + src/p_map.c | 7 +- src/p_mobj.c | 3 +- src/p_user.c | 283 ++++++++++++++++++++++++++++------------------ 8 files changed, 218 insertions(+), 117 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index fba2a6837..2c4483775 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -49,6 +49,7 @@ typedef enum SF_MULTIABILITY = 1<<13, // Revenge of Final Demo. SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) + SF_NOSUPERJUMPBOOST = 1<<16, // Disable the jump boost given while super (i.e. Knuckles) // free up to and including 1<<31 } skinflags_t; diff --git a/src/dehacked.c b/src/dehacked.c index 78120c5c4..de93ce50e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9655,6 +9655,7 @@ struct { {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, {"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER}, + {"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST}, // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, diff --git a/src/info.c b/src/info.c index 62048b64a..a9619d7c7 100644 --- a/src/info.c +++ b/src/info.c @@ -2929,11 +2929,11 @@ state_t states[NUMSTATES] = {SPR_IVSP, FF_ANIMATE, 32, {NULL}, 31, 1, S_NULL}, // S_IVSP // Super Sonic Spark - {SPR_SSPK, 0, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1 - {SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2 - {SPR_SSPK, 2, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3 - {SPR_SSPK, 1, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4 - {SPR_SSPK, 0, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5 + {SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK2}, // S_SSPK1 + {SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK3}, // S_SSPK2 + {SPR_SSPK, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK4}, // S_SSPK3 + {SPR_SSPK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_SSPK5}, // S_SSPK4 + {SPR_SSPK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_SSPK5 // Flicky-sized bubble {SPR_FBUB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_FLICKY_BUBBLE diff --git a/src/lua_baselib.c b/src/lua_baselib.c index db70a11a2..53bb6e328 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1259,6 +1259,19 @@ static int lib_pElementalFire(lua_State *L) return 0; } +static int lib_pSpawnSkidDust(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + fixed_t radius = luaL_checkfixed(L, 2); + boolean sound = lua_optboolean(L, 3); + NOHUD + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + P_SpawnSkidDust(player, radius, sound); + return 0; +} + static int lib_pDoPlayerFinish(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1346,6 +1359,19 @@ static int lib_pNukeEnemies(lua_State *L) return 0; } +static int lib_pEarthquake(lua_State *L) +{ + mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + fixed_t radius = luaL_checkfixed(L, 3); + NOHUD + INLEVEL + if (!inflictor || !source) + return LUA_ErrInvalid(L, "mobj_t"); + P_Earthquake(inflictor, source, radius); + return 0; +} + static int lib_pHomingAttack(lua_State *L) { mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3262,6 +3288,7 @@ static luaL_Reg lib[] = { {"P_DoBubbleBounce",lib_pDoBubbleBounce}, {"P_BlackOw",lib_pBlackOw}, {"P_ElementalFire",lib_pElementalFire}, + {"P_SpawnSkidDust", lib_pSpawnSkidDust}, {"P_DoPlayerFinish",lib_pDoPlayerFinish}, {"P_DoPlayerExit",lib_pDoPlayerExit}, {"P_InstaThrust",lib_pInstaThrust}, @@ -3269,6 +3296,7 @@ static luaL_Reg lib[] = { {"P_ReturnThrustY",lib_pReturnThrustY}, {"P_LookForEnemies",lib_pLookForEnemies}, {"P_NukeEnemies",lib_pNukeEnemies}, + {"P_Earthquake",lib_pEarthquake}, {"P_HomingAttack",lib_pHomingAttack}, {"P_SuperReady",lib_pSuperReady}, {"P_DoJump",lib_pDoJump}, diff --git a/src/p_local.h b/src/p_local.h index e89343ca8..f10975702 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -175,6 +175,7 @@ void P_DoAbilityBounce(player_t *player, boolean changemomz); void P_TwinSpinRejuvenate(player_t *player, mobjtype_t type); void P_BlackOw(player_t *player); void P_ElementalFire(player_t *player, boolean cropcircle); +void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound); void P_DoPityCheck(player_t *player); void P_PlayerThink(player_t *player); @@ -192,6 +193,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); +void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); diff --git a/src/p_map.c b/src/p_map.c index 18d6a1853..acfffc901 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3373,8 +3373,13 @@ static void PTR_GlideClimbTraverse(line_t *li) if (!slidemo->player->climbing) { - S_StartSound(slidemo->player->mo, sfx_s3k4a); + S_StartSound(slidemo, sfx_s3k4a); slidemo->player->climbing = 5; + if (slidemo->player->powers[pw_super]) + { + P_Earthquake(slidemo, slidemo, 256*slidemo->scale); + S_StartSound(slidemo, sfx_s3k49); + } } slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED); diff --git a/src/p_mobj.c b/src/p_mobj.c index 40d0755b3..e2d93611d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -211,7 +211,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) return P_SetPlayerMobjState(mobj, S_PLAY_FALL); // Catch swimming versus flying - if ((state == S_PLAY_FLY || state == S_PLAY_GLIDE) && player->mo->eflags & MFE_UNDERWATER && !player->skidtime) + if ((state == S_PLAY_FLY || (state == S_PLAY_GLIDE && skins[player->skin].sprites[SPR2_SWIM].numframes)) + && player->mo->eflags & MFE_UNDERWATER && !player->skidtime) return P_SetPlayerMobjState(player->mo, S_PLAY_SWIM); else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER)) { diff --git a/src/p_user.c b/src/p_user.c index 7a51e7bf3..9d23143b3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2322,6 +2322,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) } else { + P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH)) @@ -2336,23 +2337,31 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) { player->skidtime = TICRATE; P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); + P_SpawnSkidDust(player, player->mo->radius, true); // make sure the player knows they landed player->mo->tics = -1; } else if (!player->skidtime) player->pflags &= ~PF_GLIDING; } - else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY)) && player->mo->state-states == S_PLAY_FALL) + else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY)) + && (player->mo->floorz != player->mo->watertop) && player->mo->state-states == S_PLAY_FALL) { if (player->mo->state-states != S_PLAY_GLIDE_LANDING) { P_ResetPlayer(player); P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE_LANDING); - S_StartSound(player->mo, sfx_s3k4c); player->pflags |= PF_STASIS; if (player->speed > FixedMul(player->runspeed, player->mo->scale)) player->skidtime += player->mo->tics; - player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; + player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy; + if (player->powers[pw_super]) + { + P_Earthquake(player->mo, player->mo, 256*player->mo->scale); + S_StartSound(player->mo, sfx_s3k49); + } + else + S_StartSound(player->mo, sfx_s3k4c); } } else if (player->charability2 == CA2_MELEE @@ -4447,7 +4456,7 @@ void P_DoJump(player_t *player, boolean soundandstate) } else if (maptol & TOL_NIGHTS) player->mo->momz = 18*FRACUNIT; - else if (player->powers[pw_super]) + else if (player->powers[pw_super] && !(player->charflags & SF_NOSUPERJUMPBOOST)) { player->mo->momz = 13*FRACUNIT; @@ -5346,8 +5355,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { glidespeed >>= 1; playerspeed >>= 1; - player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; + if (!(player->powers[pw_super] || player->powers[pw_sneakers])) + { + player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy; + } } player->pflags |= PF_GLIDING|PF_THOKKED; @@ -5774,7 +5786,7 @@ static void P_2dMovement(player_t *player) if (player->climbing) { if (cmd->forwardmove != 0) - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1), false); // 2/3 while super player->mo->momx = 0; } @@ -5989,9 +6001,9 @@ static void P_3dMovement(player_t *player) if (cmd->forwardmove) { if (player->mo->eflags & MFE_UNDERWATER) - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 20*FRACUNIT/3 : 10*FRACUNIT), false); // 2/3 while super else - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); + P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1), false); // 2/3 while super } } else if (!(controlstyle == CS_LMAOGALOG) @@ -6024,9 +6036,9 @@ static void P_3dMovement(player_t *player) if (player->climbing) { if (player->mo->eflags & MFE_UNDERWATER) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 10*FRACUNIT)); + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, player->powers[pw_super] ? 20*FRACUNIT/3 : 10*FRACUNIT)); // 2/3 while super else - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); + P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, player->powers[pw_super] ? 5*FRACUNIT : 15*FRACUNIT>>1)); // 2/3 while super } // Analog movement control else if (controlstyle == CS_LMAOGALOG) @@ -7759,7 +7771,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) // // Spawns spindash dust randomly around the player within a certain radius. // -static void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) +void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) { mobj_t *mo = player->mo; mobj_t *particle; @@ -7797,7 +7809,7 @@ static void P_SkidStuff(player_t *player) { player->skidtime = 0; player->pflags &= ~(PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE); - player->pflags |= PF_THOKKED; // nice try, speedrunners (but for real this is just behavior from S3K) + player->pflags |= PF_THOKKED; P_SetPlayerMobjState(player->mo, S_PLAY_FALL); } // Get up and brush yourself off, idiot. @@ -7808,8 +7820,8 @@ static void P_SkidStuff(player_t *player) player->pflags |= PF_STASIS; if (player->speed > FixedMul(player->runspeed, player->mo->scale)) player->skidtime += player->mo->tics; - player->mo->momx = ((player->mo->momx - player->cmomx) >> 1) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy) >> 1) + player->cmomy; + player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx; + player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy; } // Didn't stop yet? Skid FOREVER! else if (player->skidtime == 1) @@ -8192,10 +8204,11 @@ static void P_MovePlayer(player_t *player) if (player->pflags & PF_GLIDING) { mobj_t *mo = player->mo; // seriously why isn't this at the top of the function hngngngng - fixed_t leeway = (P_ControlStyle(player) != CS_LMAOGALOG) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0; fixed_t glidespeed = player->actionspd; fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy; angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy); + boolean swimming = mo->state - states == S_PLAY_SWIM; + boolean in2d = mo->flags2 & MF2_TWOD || twodlevel; if (player->powers[pw_super] || player->powers[pw_sneakers]) glidespeed *= 2; @@ -8212,42 +8225,83 @@ static void P_MovePlayer(player_t *player) } // Strafing while gliding. - angle = mo->angle - leeway; + if ((P_ControlStyle(player) & CS_LMAOGALOG) || in2d) + angle = mo->angle; + else if (swimming) + angle = mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<angle - FixedAngle(cmd->sidemove * FRACUNIT); if (!player->skidtime) // TODO: make sure this works in 2D! { + angle_t anglediff = angle - moveangle; + fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE((anglediff >> ANGLETOFINESHIFT) & FINEMASK); fixed_t speed, scale = mo->scale; - fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0); - fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); // mamgic number BAD but this feels right - if (mo->eflags & MFE_UNDERWATER) - speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); - else - speed = FixedMul(glidespeed + player->glidetime*1500, scale); - - P_Thrust(mo, angle, FixedMul(accelfactor, scale)); - - newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - if (newMagnitude > speed) + if (in2d) { - fixed_t tempmomx, tempmomy; - if (oldMagnitude > speed) + if (mo->eflags & MFE_UNDERWATER) + speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); + else + speed = FixedMul(glidespeed + player->glidetime*1500, scale); + P_InstaThrust(mo, angle, speed); + } + else if (swimming) + { + fixed_t minspeed; + + if (anglediff > ANGLE_180) + anglediff = InvAngle(InvAngle(anglediff) >> 3); + else + anglediff = anglediff >> 3; + + minspeed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); // underwater-specific + speed = FixedHypot(momx, momy) - abs(P_ReturnThrustY(mo, anglediff, mo->scale)); + + if (speed < minspeed) { - if (newMagnitude > oldMagnitude) + momx += P_ReturnThrustX(mo, angle, FixedMul(accelfactor, scale)); + momy += P_ReturnThrustY(mo, angle, FixedMul(accelfactor, scale)); + speed = FixedHypot(momx, momy); // recalculate speed + } + + mo->momx = P_ReturnThrustX(mo, moveangle + anglediff, speed) + player->cmomx; + mo->momy = P_ReturnThrustY(mo, moveangle + anglediff, speed) + player->cmomy; + } + else + { + fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0); + fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); + + if (mo->eflags & MFE_UNDERWATER) + speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); + else + speed = FixedMul(glidespeed + player->glidetime*1500, scale); + + P_Thrust(mo, angle, FixedMul(accelfactor, scale)); + + newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); + if (newMagnitude > speed) + { + fixed_t tempmomx, tempmomy; + if (oldMagnitude > speed) { - tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude); - tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude); + if (newMagnitude > oldMagnitude) + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude); + player->mo->momx = tempmomx + player->cmomx; + player->mo->momy = tempmomy + player->cmomy; + } + // else do nothing + } + else + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), speed); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), speed); player->mo->momx = tempmomx + player->cmomx; player->mo->momy = tempmomy + player->cmomy; } - // else do nothing - } - else - { - tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), speed); - tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), speed); - player->mo->momx = tempmomx + player->cmomx; - player->mo->momy = tempmomy + player->cmomy; } } } @@ -8563,6 +8617,7 @@ static void P_MovePlayer(player_t *player) || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) || (player->pflags & PF_SPINNING) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) player->mo->height = P_GetPlayerSpinHeight(player); else @@ -8628,74 +8683,6 @@ static void P_MovePlayer(player_t *player) if (CheckForBustableBlocks) P_CheckBustableBlocks(player); - // Special handling for - // gliding in 2D mode - if ((twodlevel || player->mo->flags2 & MF2_TWOD) && player->pflags & PF_GLIDING && player->charability == CA_GLIDEANDCLIMB - && !(player->mo->flags & MF_NOCLIP)) - { - msecnode_t *node; // only place it's being used in P_MovePlayer now - fixed_t oldx; - fixed_t oldy; - fixed_t floorz, ceilingz; - - oldx = player->mo->x; - oldy = player->mo->y; - - P_UnsetThingPosition(player->mo); - player->mo->x += player->mo->momx; - player->mo->y += player->mo->momy; - P_SetThingPosition(player->mo); - - for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (!node->m_sector) - break; - - if (node->m_sector->ffloors) - { - ffloor_t *rover; - fixed_t topheight, bottomheight; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - if (topheight > player->mo->z && bottomheight < player->mo->z) - { - P_ResetPlayer(player); - S_StartSound(player->mo, sfx_s3k4a); - player->climbing = 5; - player->mo->momx = player->mo->momy = player->mo->momz = 0; - break; - } - } - } - - floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); - ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); - - if (player->mo->z+player->mo->height > ceilingz - && node->m_sector->ceilingpic == skyflatnum) - continue; - - if (floorz > player->mo->z || ceilingz < player->mo->z) - { - P_ResetPlayer(player); - S_StartSound(player->mo, sfx_s3k4a); - player->climbing = 5; - player->mo->momx = player->mo->momy = player->mo->momz = 0; - break; - } - } - P_UnsetThingPosition(player->mo); - player->mo->x = oldx; - player->mo->y = oldy; - P_SetThingPosition(player->mo); - } - // Check for a BOUNCY sector! if (CheckForBouncySector) P_CheckBouncySectors(player); @@ -9001,6 +8988,82 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) } } +// +// P_Earthquake +// Used for Super Knuckles' landing - damages enemies within the given radius +// If inflictor is grounded, only grounded enemies are hurt +// +void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius) +{ + const fixed_t ns = radius/12; + mobj_t *mo; + angle_t fa; + thinker_t *think; + INT32 i; + boolean grounded = P_IsObjectOnGround(inflictor); + + for (i = 0; i < 16; i++) + { + fa = (i*(FINEANGLES/16)); + mo = P_SpawnMobjFromMobj(inflictor, 0, 0, 0, MT_SUPERSPARK); + if (!P_MobjWasRemoved(mo)) + { + if (grounded) + { + mo->momx = FixedMul(FINESINE(fa),ns); + mo->momy = FixedMul(FINECOSINE(fa),ns); + } + else + { + P_InstaThrust(mo, inflictor->angle + ANGLE_90, FixedMul(FINECOSINE(fa),ns)); + mo->momz = FixedMul(FINESINE(fa),ns); + } + } + } + + if (inflictor->player && P_IsLocalPlayer(inflictor->player)) + { + quake.epicenter = NULL; + quake.intensity = 8*FRACUNIT; + quake.time = 8; + quake.radius = radius; + } + + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)think; + + if (grounded && !P_IsObjectOnGround(mo)) + continue; + + if (!(mo->flags & MF_SHOOTABLE) && !(mo->type == MT_EGGGUARD || mo->type == MT_MINUS)) + continue; + + if (mo->flags & MF_MONITOR) + continue; // Monitors cannot be 'nuked'. + + if (mo->type == MT_PLAYER) + continue; // Don't hurt players + + if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) + continue; // Workaround for possible integer overflow in the below -Red + + if (P_AproxDistance(P_AproxDistance(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) + continue; + + if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) + mo->flags = (mo->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; + + if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! + P_KillMobj(mo->tracer, inflictor, source, 0); + + P_DamageMobj(mo, inflictor, source, 1, 0); + } +} + // // P_LookForFocusTarget // Looks for a target for a player to focus on, for Z-targeting etc. From 7e72009a87bd27d4f3acd7c2c923eee8fa350c31 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Sat, 4 Jul 2020 03:21:48 +0800 Subject: [PATCH 36/42] Fix buildbot warning --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 9d23143b3..beb2eedb1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8271,7 +8271,6 @@ static void P_MovePlayer(player_t *player) else { fixed_t newMagnitude, oldMagnitude = R_PointToDist2(momx, momy, 0, 0); - fixed_t accelfactor = 4*FRACUNIT - 3*FINECOSINE(((angle-moveangle) >> ANGLETOFINESHIFT) & FINEMASK); if (mo->eflags & MFE_UNDERWATER) speed = FixedMul((glidespeed>>1) + player->glidetime*750, scale); From 84000a0add2643b68f9b603d699f45ccc6fed7fd Mon Sep 17 00:00:00 2001 From: Lachlan Date: Sat, 4 Jul 2020 04:00:28 +0800 Subject: [PATCH 37/42] P_Earthquake: Use P_RadiusAttack in favor of thinker iteration --- src/p_map.c | 2 +- src/p_user.c | 45 ++++++--------------------------------------- 2 files changed, 7 insertions(+), 40 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index acfffc901..a8cb33f1b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3377,7 +3377,7 @@ static void PTR_GlideClimbTraverse(line_t *li) slidemo->player->climbing = 5; if (slidemo->player->powers[pw_super]) { - P_Earthquake(slidemo, slidemo, 256*slidemo->scale); + P_Earthquake(slidemo, slidemo, 256*FRACUNIT); S_StartSound(slidemo, sfx_s3k49); } } diff --git a/src/p_user.c b/src/p_user.c index beb2eedb1..f973a7726 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2357,7 +2357,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy; if (player->powers[pw_super]) { - P_Earthquake(player->mo, player->mo, 256*player->mo->scale); + P_Earthquake(player->mo, player->mo, 256*FRACUNIT); S_StartSound(player->mo, sfx_s3k49); } else @@ -8990,14 +8990,13 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) // // P_Earthquake // Used for Super Knuckles' landing - damages enemies within the given radius -// If inflictor is grounded, only grounded enemies are hurt // void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius) { - const fixed_t ns = radius/12; + const fixed_t scaledradius = FixedMul(radius, inflictor->scale); + const fixed_t ns = scaledradius/12; mobj_t *mo; angle_t fa; - thinker_t *think; INT32 i; boolean grounded = P_IsObjectOnGround(inflictor); @@ -9023,44 +9022,12 @@ void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (inflictor->player && P_IsLocalPlayer(inflictor->player)) { quake.epicenter = NULL; - quake.intensity = 8*FRACUNIT; + quake.intensity = 8*inflictor->scale; quake.time = 8; - quake.radius = radius; + quake.radius = scaledradius; } - for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) - { - if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo = (mobj_t *)think; - - if (grounded && !P_IsObjectOnGround(mo)) - continue; - - if (!(mo->flags & MF_SHOOTABLE) && !(mo->type == MT_EGGGUARD || mo->type == MT_MINUS)) - continue; - - if (mo->flags & MF_MONITOR) - continue; // Monitors cannot be 'nuked'. - - if (mo->type == MT_PLAYER) - continue; // Don't hurt players - - if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) - continue; // Workaround for possible integer overflow in the below -Red - - if (P_AproxDistance(P_AproxDistance(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) - continue; - - if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) - mo->flags = (mo->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; - - if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! - P_KillMobj(mo->tracer, inflictor, source, 0); - - P_DamageMobj(mo, inflictor, source, 1, 0); - } + P_RadiusAttack(inflictor, source, radius, 0); } // From e44d93f76b4e51cf71ee4a6abdc5bc0e187abb5b Mon Sep 17 00:00:00 2001 From: Lachlan Date: Sat, 4 Jul 2020 04:30:57 +0800 Subject: [PATCH 38/42] Fix skiddust positional scaling --- src/p_user.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f973a7726..84fbd2e81 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7776,11 +7776,14 @@ void P_SpawnSkidDust(player_t *player, fixed_t radius, boolean sound) mobj_t *mo = player->mo; mobj_t *particle; - radius >>= FRACBITS; - if (radius) - particle = P_SpawnMobjFromMobj(mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST); - else - particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST); + particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST); + if (radius >>= FRACBITS) + { + P_UnsetThingPosition(particle); + particle->x += P_RandomRange(-radius, radius) << FRACBITS; + particle->y += P_RandomRange(-radius, radius) << FRACBITS; + P_SetThingPosition(particle); + } particle->tics = 10; particle->destscale = (2*mo->scale)/3; From cdb247d08f16bd1667e2c2e7838bbb061bcad409 Mon Sep 17 00:00:00 2001 From: Lachlan Date: Sat, 4 Jul 2020 05:25:34 +0800 Subject: [PATCH 39/42] Fix compiler warning --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index c9342a74f..ad044c978 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2933,7 +2933,7 @@ static boolean P_ThingHeightClip(mobj_t *thing) boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz); ffloor_t *rover = NULL; boolean bouncing; - boolean hitfloor; + boolean hitfloor = false; if (thing->flags & MF_NOCLIPHEIGHT) return true; From 527e682931aa9af44f473b148079bccc6341e9de Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 4 Jul 2020 18:27:06 +0800 Subject: [PATCH 40/42] Add sightcheck boolean to P_RadiusAttack Also now destroys Egg Guard shields, and circumstantially Minuses --- src/lua_baselib.c | 3 ++- src/p_enemy.c | 12 ++++++------ src/p_local.h | 2 +- src/p_map.c | 16 ++++++++++++---- src/p_mobj.c | 2 +- src/p_user.c | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 53bb6e328..775d9ec02 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1580,11 +1580,12 @@ static int lib_pRadiusAttack(lua_State *L) mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); fixed_t damagedist = luaL_checkfixed(L, 3); UINT8 damagetype = luaL_optinteger(L, 4, 0); + boolean sightcheck = lua_opttrueboolean(L, 5); NOHUD INLEVEL if (!spot || !source) return LUA_ErrInvalid(L, "mobj_t"); - P_RadiusAttack(spot, source, damagedist, damagetype); + P_RadiusAttack(spot, source, damagedist, damagetype, sightcheck); return 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index a38496d99..c26d5c279 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3858,7 +3858,7 @@ void A_Explode(mobj_t *actor) if (LUA_CallAction("A_Explode", actor)) return; - P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1); + P_RadiusAttack(actor, actor->target, actor->info->damage, locvar1, true); } // Function: A_BossDeath @@ -5639,7 +5639,7 @@ void A_MinusPopup(mobj_t *actor) P_SetObjectMomZ(rock, 3*FRACUNIT, false); P_SetScale(rock, rock->scale/3); } - P_RadiusAttack(actor, actor, 2*actor->radius, 0); + P_RadiusAttack(actor, actor, 2*actor->radius, 0, true); if (actor->tracer) P_DamageMobj(actor->tracer, actor, actor, 1, 0); @@ -11032,7 +11032,7 @@ void A_VileAttack(mobj_t *actor) actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); - P_RadiusAttack(fire, actor, 70*FRACUNIT, 0); + P_RadiusAttack(fire, actor, 70*FRACUNIT, 0, true); } else { @@ -11077,7 +11077,7 @@ void A_VileAttack(mobj_t *actor) actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); - P_RadiusAttack(fire, actor, 70*FRACUNIT, 0); + P_RadiusAttack(fire, actor, 70*FRACUNIT, 0, true); } } @@ -12313,7 +12313,7 @@ void A_MineExplode(mobj_t *actor) quake.intensity = 8*FRACUNIT; quake.time = TICRATE/3; - P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF); + P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true); P_MobjCheckWater(actor); { @@ -13314,7 +13314,7 @@ void A_Boss5BombExplode(mobj_t *actor) actor->flags2 = MF2_EXPLOSION; if (actor->target) - P_RadiusAttack(actor, actor->target, 7*actor->radius, 0); + P_RadiusAttack(actor, actor->target, 7*actor->radius, 0, true); P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale); P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); diff --git a/src/p_local.h b/src/p_local.h index f10975702..9873a20af 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -421,7 +421,7 @@ void P_DelPrecipSeclist(mprecipsecnode_t *node); void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y); void P_Initsecnode(void); -void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype); +void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype, boolean sightcheck); fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height); boolean PIT_PushableMoved(mobj_t *thing); diff --git a/src/p_map.c b/src/p_map.c index a8cb33f1b..bd1e8d7e4 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4015,6 +4015,7 @@ static fixed_t bombdamage; static mobj_t *bombsource; static mobj_t *bombspot; static UINT8 bombdamagetype; +static boolean bombsightcheck; // // PIT_RadiusAttack @@ -4028,10 +4029,16 @@ static boolean PIT_RadiusAttack(mobj_t *thing) if (thing == bombspot) // ignore the bomb itself (Deton fix) return true; - if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE) + if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.) return true; - if (bombsource && thing->type == bombsource->type && !(bombdamagetype & DMG_CANHURTSELF)) // ignore the type of guys who dropped the bomb (Jetty-Syn Bomber or Skim can bomb eachother, but not themselves.) + if (thing->type == MT_MINUS && !(thing->flags & (MF_SPECIAL|MF_SHOOTABLE)) && !bombsightcheck) + thing->flags = (thing->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; + + if (thing->type == MT_EGGGUARD && thing->tracer) //nuke Egg Guard's shield! + P_KillMobj(thing->tracer, bombspot, bombsource, bombdamagetype); + + if ((thing->flags & (MF_MONITOR|MF_SHOOTABLE)) != MF_SHOOTABLE) return true; dx = abs(thing->x - bombspot->x); @@ -4053,7 +4060,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z) return true; - if (P_CheckSight(thing, bombspot)) + if (!bombsightcheck || P_CheckSight(thing, bombspot)) { // must be in direct path P_DamageMobj(thing, bombspot, bombsource, 1, bombdamagetype); // Tails 01-11-2001 } @@ -4065,7 +4072,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) // P_RadiusAttack // Source is the creature that caused the explosion at spot. // -void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype) +void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 damagetype, boolean sightcheck) { INT32 x, y; INT32 xl, xh, yl, yh; @@ -4083,6 +4090,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama bombsource = source; bombdamage = FixedMul(damagedist, spot->scale); bombdamagetype = damagetype; + bombsightcheck = sightcheck; for (y = yl; y <= yh; y++) for (x = xl; x <= xh; x++) diff --git a/src/p_mobj.c b/src/p_mobj.c index e2d93611d..101440b79 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -880,7 +880,7 @@ void P_ExplodeMissile(mobj_t *mo) if (mo->type == MT_DETON) { - P_RadiusAttack(mo, mo, 96*FRACUNIT, 0); + P_RadiusAttack(mo, mo, 96*FRACUNIT, 0, true); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); P_SetScale(explodemo, mo->scale); diff --git a/src/p_user.c b/src/p_user.c index 84fbd2e81..352200aaf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9030,7 +9030,7 @@ void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius) quake.radius = scaledradius; } - P_RadiusAttack(inflictor, source, radius, 0); + P_RadiusAttack(inflictor, source, radius, 0, false); } // From 17daf2faa29f3746071745f995f06c8482604e3d Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 4 Jul 2020 19:17:38 +0800 Subject: [PATCH 41/42] Reduce speed cut when gliding underwater --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 352200aaf..0153056de 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5354,11 +5354,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (player->mo->eflags & MFE_UNDERWATER) { glidespeed >>= 1; - playerspeed >>= 1; + playerspeed = 2*playerspeed/3; if (!(player->powers[pw_super] || player->powers[pw_sneakers])) { - player->mo->momx = ((player->mo->momx - player->cmomx)/2) + player->cmomx; - player->mo->momy = ((player->mo->momy - player->cmomy)/2) + player->cmomy; + player->mo->momx = (2*(player->mo->momx - player->cmomx)/3) + player->cmomx; + player->mo->momy = (2*(player->mo->momy - player->cmomy)/3) + player->cmomy; } } From 96bccd5f9fce48683d9cb280647a75e5fd05da6e Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 4 Jul 2020 12:59:56 -0700 Subject: [PATCH 42/42] Credit Oni for CODE --- src/f_finale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/f_finale.c b/src/f_finale.c index 2ce8fd101..eb6e283ad 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1165,6 +1165,7 @@ static const char *credits[] = { "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible "Wessel \"sphere\" Smit", "Ben \"Cue\" Woodford", + "\"VelocitOni\"", // Wrote the original dashmode script "Ikaro \"Tatsuru\" Vinhas", // Git contributors with 5+ approved merges of substantive quality, // or contributors with at least one groundbreaking merge, may be named.