diff --git a/src/k_kart.c b/src/k_kart.c index 40956016..8d206bf4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -966,6 +966,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) @@ -986,7 +996,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; @@ -1021,11 +1031,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; @@ -1077,7 +1083,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; } @@ -1087,7 +1093,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); @@ -1131,6 +1137,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 diff --git a/src/k_kart.h b/src/k_kart.h index 9865d373..8989e58e 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 7c44c796..5ae801a9 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 88045a3e..6e8bd8bb 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