diff --git a/src/d_player.h b/src/d_player.h index 3262defa3..34eb385ca 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -298,6 +298,7 @@ typedef enum k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse. k_waterskip, // Water skipping counter k_dashpadcooldown, // Separate the vanilla SA-style dash pads from using pw_flashing + k_boostpower, // Base boost value, for offroad k_speedboost, // Boost value smoothing for max speed k_accelboost, // Boost value smoothing for acceleration k_boostcam, // Camera push forward on boost diff --git a/src/dehacked.c b/src/dehacked.c index 78d6c4df3..64d83e2f4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7685,6 +7685,7 @@ static const char *const KARTSTUFF_LIST[] = { "BRAKESTOP", "WATERSKIP", "DASHPADCOOLDOWN", + "BOOSTPOWER", "SPEEDBOOST", "ACCELBOOST", "BOOSTCAM", diff --git a/src/info.c b/src/info.c index 75a7655f0..f6ac04597 100644 --- a/src/info.c +++ b/src/info.c @@ -2797,7 +2797,7 @@ state_t states[NUMSTATES] = {SPR_THNS, 10, 2, {NULL}, 0, 0, S_THUNDERSHIELD24}, // S_THUNDERSHIELD23 {SPR_THNS, 11, 2, {NULL}, 0, 0, S_THUNDERSHIELD1}, // S_THUNDERSHIELD24 - {SPR_SINK, 0, 4, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK + {SPR_SINK, 0, 1, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK {SPR_SINK, 0|FF_TRANS80|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_SINK_SHIELD}, // S_SINK_SHIELD {SPR_SITR, 0, 1, {NULL}, 0, 0, S_SINKTRAIL2}, // S_SINKTRAIL1 {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 @@ -2987,7 +2987,7 @@ state_t states[NUMSTATES] = {SPR_ARRO, FF_FULLBRIGHT|1, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_BOX {SPR_ITEM, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_ITEM {SPR_ITMN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_NUMBER - {SPR_ITMN, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_X + {SPR_ITMN, FF_FULLBRIGHT|11, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_X {SPR_WANT, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_PLAYERARROW_WANTED2}, // S_PLAYERARROW_WANTED1 {SPR_WANT, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED3}, // S_PLAYERARROW_WANTED2 {SPR_WANT, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED4}, // S_PLAYERARROW_WANTED3 diff --git a/src/k_kart.c b/src/k_kart.c index 0c75635be..cac6c471e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -967,6 +967,16 @@ static fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) else weight = (mobj->player->kartweight)<player) + { + if (against->player->kartstuff[k_invincibilitytimer] + || against->player->kartstuff[k_growshrinktimer] > 0) + weight = 0; + else + weight = (against->player->kartweight)<player) @@ -987,7 +997,7 @@ static fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) return weight; } -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) +void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce) { mobj_t *fx; fixed_t momdifx, momdify; @@ -1022,11 +1032,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) } mass1 = K_GetMobjWeight(mobj1, mobj2); - - if (solid == true && mass1 > 0) - mass2 = mass1; - else - mass2 = K_GetMobjWeight(mobj2, mobj1); + mass2 = K_GetMobjWeight(mobj2, mobj1); momdifx = mobj1->momx - mobj2->momx; momdify = mobj1->momy - mobj2->momy; @@ -1078,7 +1084,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) fixed_t newz = mobj1->momz; if (mass2 > 0) mobj1->momz = mobj2->momz; - if (mass1 > 0 && solid == false) + if (mass1 > 0) mobj2->momz = newz; } @@ -1088,7 +1094,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) mobj1->momy = mobj1->momy - FixedMul(FixedMul(FixedDiv(2*mass2, mass1 + mass2), p), disty); } - if (mass1 > 0 && solid == false) + if (mass1 > 0) { mobj2->momx = mobj2->momx - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -distx); mobj2->momy = mobj2->momy - FixedMul(FixedMul(FixedDiv(2*mass1, mass1 + mass2), p), -disty); @@ -1132,6 +1138,83 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) } } +// Alternate version for solid objects; always pushes away from the solid object, doesn't take anything else into account. + +void K_KartSolidBouncing(mobj_t *solid, mobj_t *mo) +{ + fixed_t mmomx = 0, mmomy = 0; + + if (!solid || !mo) + return; + + // Don't bump when you're being reborn + if (mo->player && mo->player->playerstate != PST_LIVE) + return; + + if (mo->player && mo->player->kartstuff[k_respawn]) + return; + + if (mo->eflags & MFE_JUSTBOUNCEDWALL) + { + P_SlideMove(mo, true); + return; + } + + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; + + if (mo->player->kartstuff[k_drift] != 0) // SRB2kart + { + mo->player->kartstuff[k_drift] = 0; + mo->player->kartstuff[k_driftcharge] = 0; + } + else + { + mmomx = mo->momx; + mmomy = mo->momy; + } + + mmomx = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mmomy = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + + { + mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); + if (mo->eflags & MFE_VERTICALFLIP) + fx->eflags |= MFE_VERTICALFLIP; + else + fx->eflags &= ~MFE_VERTICALFLIP; + fx->scale = mo->scale; + + S_StartSound(mo, sfx_s3k49); + } + + { + angle_t pushangle; + fixed_t movelen; + + pushangle = R_PointToAngle2(solid->x, solid->y, mo->x, mo->y); + + pushangle >>= ANGLETOFINESHIFT; + + movelen = P_AproxDistance(mmomx, mmomy); + + if (mo->player && movelen < (15*mapheaderinfo[gamemap-1]->mobj_scale)) + movelen = (15*mapheaderinfo[gamemap-1]->mobj_scale); + + mmomx += FixedMul(movelen, FINECOSINE(pushangle)); + mmomy += FixedMul(movelen, FINESINE(pushangle)); + } + + mo->eflags |= MFE_JUSTBOUNCEDWALL; + + mo->momx = mmomx; + mo->momy = mmomy; + mo->player->cmomx = mmomx; + mo->player->cmomy = mmomy; + + P_TryMove(mo, mo->x + mmomx, mo->y + mmomy, true); +} + /** \brief Checks that the player is on an offroad subsector for realsies \param mo player mobj object @@ -1451,7 +1534,7 @@ static void K_GetKartBoostPower(player_t *player) if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow] == 1) // Slow down after you've been bumped { - player->kartstuff[k_speedboost] = player->kartstuff[k_accelboost] = 0; + player->kartstuff[k_boostpower] = player->kartstuff[k_speedboost] = player->kartstuff[k_accelboost] = 0; return; } @@ -1502,13 +1585,15 @@ static void K_GetKartBoostPower(player_t *player) // don't average them anymore, this would make a small boost and a high boost less useful // just take the highest we want instead - if (boostpower + speedboost > player->kartstuff[k_speedboost]) - player->kartstuff[k_speedboost] = boostpower + speedboost; // Immediate increase if higher - else - player->kartstuff[k_speedboost] += ((boostpower + speedboost) - player->kartstuff[k_speedboost])/TICRATE; // Smoothly decrease if lower + player->kartstuff[k_boostpower] = boostpower; - // Accel isn't affected by boostpower, hence the FRACUNIT. Probably for making acceleration feel consistent in offroad. - player->kartstuff[k_accelboost] = FRACUNIT + accelboost; + // value smoothing + if (speedboost > player->kartstuff[k_speedboost]) + player->kartstuff[k_speedboost] = speedboost; + else + player->kartstuff[k_speedboost] += (speedboost - player->kartstuff[k_speedboost])/(TICRATE/2); + + player->kartstuff[k_accelboost] = accelboost; } fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) @@ -1543,7 +1628,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) finalspeed = FixedMul(FixedMul(k_speed<<14, g_cc), player->mo->scale); if (doboostpower) - return FixedMul(finalspeed, player->kartstuff[k_speedboost]); + return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]); return finalspeed; } @@ -1558,7 +1643,7 @@ fixed_t K_GetKartAccel(player_t *player) //k_accel += 3 * (9 - kartspeed); // 36 - 60 k_accel += 4 * (9 - kartspeed); // 32 - 64 - return FixedMul(k_accel, player->kartstuff[k_accelboost]); + return FixedMul(k_accel, FRACUNIT+player->kartstuff[k_accelboost]); } UINT16 K_GetKartFlashing(player_t *player) @@ -2702,9 +2787,8 @@ void K_DoSneaker(player_t *player, boolean doPFlag) K_PlayTauntSound(player->mo); K_GetKartBoostPower(player); - - // Push the camera forward, the amount depending on how much the speed boost increases - player->kartstuff[k_destboostcam] = FixedMul(FRACUNIT, player->kartstuff[k_speedboost]-prevboost); + if (player->kartstuff[k_speedboost] > prevboost) + player->kartstuff[k_destboostcam] = FRACUNIT; } static void K_DoShrink(player_t *player) @@ -3286,10 +3370,6 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) if (player->kartstuff[k_hyudorotimer]) continue; - // Z pos too high/low - if (abs(player->mo->z - (actor->z + actor->momz)) > 48<angle - R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y); if (thisang > ANGLE_180) @@ -3317,9 +3397,13 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) if (player->kartstuff[k_bumper] <= 0) continue; + // Z pos too high/low + if (abs(player->mo->z - (actor->z + actor->momz)) > RING_DIST/8) + continue; + thisdist = P_AproxDistance(player->mo->x - (actor->x + actor->momx), player->mo->y - (actor->y + actor->momy)); - if (thisdist > RING_DIST) // Don't go for people who are too far away + if (thisdist > 2*RING_DIST) // Don't go for people who are too far away continue; thisavg = (AngleFixed(thisang) + thisdist) / 2; @@ -3411,13 +3495,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_boostcam] < player->kartstuff[k_destboostcam] && player->kartstuff[k_destboostcam] != 0) { - player->kartstuff[k_boostcam] += FRACUNIT/8; + player->kartstuff[k_boostcam] += FRACUNIT/5; if (player->kartstuff[k_boostcam] >= player->kartstuff[k_destboostcam]) player->kartstuff[k_destboostcam] = 0; } else { - player->kartstuff[k_boostcam] -= FRACUNIT/8; + player->kartstuff[k_boostcam] -= FRACUNIT/5; if (player->kartstuff[k_boostcam] < player->kartstuff[k_destboostcam]) player->kartstuff[k_boostcam] = player->kartstuff[k_destboostcam] = 0; } diff --git a/src/k_kart.h b/src/k_kart.h index bbef6c000..f1e45214a 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -20,7 +20,8 @@ void K_RegisterKartStuff(void); boolean K_IsPlayerLosing(player_t *player); boolean K_IsPlayerWanted(player_t *player); -void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); +void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce); +void K_KartSolidBouncing(mobj_t *solid, mobj_t *mo); void K_RespawnChecker(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7c44c7962..5ae801a96 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2081,13 +2081,25 @@ static int lib_kKartBouncing(lua_State *L) mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mobj2 = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); boolean bounce = luaL_checkboolean(L, 3); - boolean solid = luaL_checkboolean(L, 4); NOHUD if (!mobj1) return LUA_ErrInvalid(L, "mobj_t"); if (!mobj2) return LUA_ErrInvalid(L, "mobj_t"); - K_KartBouncing(mobj1, mobj2, bounce, solid); + K_KartBouncing(mobj1, mobj2, bounce); + return 0; +} + +static int lib_kKartSolidBouncing(lua_State *L) +{ + mobj_t *solid = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + NOHUD + if (!solid) + return LUA_ErrInvalid(L, "mobj_t"); + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + K_KartSolidBouncing(solid, mo); return 0; } @@ -2242,8 +2254,8 @@ static int lib_kDoPogoSpring(lua_State *L) static int lib_kKillBananaChain(lua_State *L) { mobj_t *banana = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - mobj_t *source = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + mobj_t *source = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); NOHUD if (!banana) return LUA_ErrInvalid(L, "mobj_t"); @@ -2265,6 +2277,19 @@ static int lib_kRepairOrbitChain(lua_State *L) return 0; } +static int lib_kFindJawzTarget(lua_State *L) +{ + mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + player_t *source = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + NOHUD // HUDSAFE? + if (!actor) + return LUA_ErrInvalid(L, "mobj_t"); + if (!source) + return LUA_ErrInvalid(L, "player_t"); + LUA_PushUserdata(L, K_FindJawzTarget(actor, source), META_PLAYER); + return 0; +} + static int lib_kMomentumToFacing(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2487,6 +2512,7 @@ static luaL_Reg lib[] = { {"K_IsPlayerLosing",lib_kIsPlayerLosing}, {"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_KartBouncing",lib_kKartBouncing}, + {"K_KartSolidBouncing",lib_kKartSolidBouncing}, {"K_DoInstashield",lib_kDoInstashield}, {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, @@ -2501,6 +2527,7 @@ static luaL_Reg lib[] = { {"K_DoPogoSpring",lib_kDoPogoSpring}, {"K_KillBananaChain",lib_kKillBananaChain}, {"K_RepairOrbitChain",lib_kRepairOrbitChain}, + {"K_FindJawzTarget",lib_kFindJawzTarget}, {"K_MomentumToFacing",lib_kMomentumToFacing}, {"K_GetKartSpeed",lib_kGetKartSpeed}, {"K_GetKartAccel",lib_kGetKartAccel}, diff --git a/src/p_map.c b/src/p_map.c index c97ee9091..ca40c27aa 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -695,7 +695,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { // Player Damage P_DamageMobj(thing, tmthing, tmthing->target, 1); - K_KartBouncing(thing, tmthing, false, false); + K_KartBouncing(thing, tmthing, false); if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD) S_StartSound(thing, sfx_s3k7b); @@ -978,7 +978,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // Player Damage P_DamageMobj(tmthing, thing, thing->target, 1); - K_KartBouncing(tmthing, thing, false, false); + K_KartBouncing(tmthing, thing, false); if (thing->type == MT_ORBINAUT || thing->type == MT_JAWZ || thing->type == MT_JAWZ_DUD) S_StartSound(tmthing, sfx_s3k7b); @@ -1084,7 +1084,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - K_KartBouncing(thing, tmthing, false, false); + K_KartBouncing(thing, tmthing, false); } if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 @@ -1506,7 +1506,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (P_IsObjectOnGround(thing) && tmthing->momz < 0) { - K_KartBouncing(tmthing, thing, true, false); + K_KartBouncing(tmthing, thing, true); if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { K_StealBumper(tmthing->player, thing->player, false); @@ -1515,7 +1515,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) { - K_KartBouncing(thing, tmthing, true, false); + K_KartBouncing(thing, tmthing, true); if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { K_StealBumper(thing->player, tmthing->player, false); @@ -1523,7 +1523,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } } else - K_KartBouncing(tmthing, thing, false, false); + K_KartBouncing(tmthing, thing, false); if (G_BattleGametype()) { @@ -1549,12 +1549,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (P_IsObjectOnGround(thing) && tmthing->momz < 0) - K_KartBouncing(tmthing, thing, true, true); - else - K_KartBouncing(tmthing, thing, false, true); - - return true; + K_KartSolidBouncing(thing, tmthing); + return false; } // Are you touching the side of the object you're interacting with? else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height diff --git a/src/p_mobj.c b/src/p_mobj.c index dc4ac0365..8405d6517 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7039,7 +7039,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->tracer->destscale = scale; if (mobj->target->player->kartstuff[k_itemamount] >= numberdisplaymin - && mobj->target->player->kartstuff[k_itemamount] < 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V + && mobj->target->player->kartstuff[k_itemamount] <= 10) // Meh, too difficult to support greater than this; convert this to a decent HUD object and then maybe :V { mobj_t *number = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); mobj_t *numx = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_OVERLAY); diff --git a/src/p_user.c b/src/p_user.c index d2631010d..30370dc81 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8373,8 +8373,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->speed > K_GetKartSpeed(player, false)) dist += 4*(player->speed - K_GetKartSpeed(player, false)); + if (player->kartstuff[k_boostcam]) + { dist -= FixedMul(dist/2, player->kartstuff[k_boostcam]); + height -= FixedMul(height, player->kartstuff[k_boostcam]); + } if (player->climbing || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG))) dist <<= 1;