diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9c26d4f6..fafc92f3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -520,8 +520,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]); for (j = 0; j < NUMKARTSTUFF; ++j) rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart - for (j = 0; j < MAXPLAYERS; ++j) - rsp->collide[j] = (UINT8)players[i].collide[j]; // SRB2kart // Score is resynched in the rspfirm resync packet rsp->health = 0; // resynched with mo health @@ -654,8 +652,6 @@ static void resynch_read_player(resynch_pak *rsp) players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]); for (j = 0; j < NUMKARTSTUFF; ++j) players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart - for (j = 0; j < MAXPLAYERS; ++j) - players[i].collide[j] = (UINT8)rsp->collide[j]; // SRB2kart // Score is resynched in the rspfirm resync packet players[i].health = rsp->health; diff --git a/src/d_player.h b/src/d_player.h index e6ceb0f2..9e59b341 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -368,7 +368,6 @@ typedef struct player_s // SRB2kart stuff INT32 kartstuff[NUMKARTSTUFF]; - boolean collide[MAXPLAYERS]; // Bit flags. // See pflags_t, above. diff --git a/src/g_game.c b/src/g_game.c index 6d9e4f74..673964be 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2124,7 +2124,6 @@ static inline void G_PlayerFinishLevel(INT32 player) memset(p->powers, 0, sizeof (p->powers)); memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart - memset(p->collide, 0, sizeof (p->collide)); // SRB2kart p->ringweapons = 0; p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility diff --git a/src/k_kart.c b/src/k_kart.c index 458357e3..2de5fe15 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1061,84 +1061,64 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) //{ SRB2kart p_user.c Stuff -boolean K_IsTouching(mobj_t *mobj1, mobj_t *mobj2) +void K_KartBilliards(mobj_t *mobj1, mobj_t *mobj2, boolean bounce) { - if (mobj1 == NULL || mobj2 == NULL) - return false; - fixed_t absx = abs(mobj1->x - mobj2->x); - fixed_t absy = abs(mobj1->y - mobj2->y); - fixed_t absz = abs(mobj1->z - mobj2->z); - - if (absx < 32*FRACUNIT && absy < 32*FRACUNIT && absz < 32*FRACUNIT) - return true; - else - return false; -} - -void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce) -{ - fixed_t newx, newy; mobj_t *fx; + fixed_t ndistx, ndisty, ndistlength; + fixed_t a1, a2; + fixed_t optimizedP; + fixed_t mass1, mass2; - if (mobj1 == NULL || mobj2 == NULL) + if (!mobj1 || !mobj2) return; - fixed_t meanX = (mobj1->momx + mobj2->momx) / 2; - fixed_t meanY = (mobj1->momy + mobj2->momy) / 2; - fixed_t deltaV1 = P_AproxDistance((mobj1->momx - meanX), (mobj1->momy - meanY)); - fixed_t deltaV2 = P_AproxDistance((mobj2->momx - meanX), (mobj2->momy - meanY)); - //fixed_t clashvolume = (deltaV1 / FRACUNIT) * 8; // In case you want to do a scaling bump sound volume. if (cv_collidesounds.value == 1) { S_StartSound(mobj1, cv_collidesoundnum.value); - //S_StartSound(mobj2, cv_collidesoundnum.value); } - fx = P_SpawnMobj((mobj1->x + mobj2->x)/2, (mobj1->y + mobj2->y)/2, (mobj1->z + mobj2->z)/2, MT_BUMP); + fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP); if (mobj1->eflags & MFE_VERTICALFLIP) fx->eflags |= MFE_VERTICALFLIP; else fx->eflags &= ~MFE_VERTICALFLIP; fx->scale = mobj1->scale; - - if (deltaV1 < (cv_collideminimum.value * FRACUNIT / 2)) - { - fixed_t a = 0; - if (deltaV1 != 0) - a = FixedDiv((cv_collideminimum.value * FRACUNIT / 2), deltaV1); - else if (deltaV2 != 0) - a = FixedDiv((cv_collideminimum.value * FRACUNIT / 2), deltaV2); - else - a = 0; - fixed_t deltax1 = (mobj1->momx - meanX); - fixed_t deltax2 = (mobj2->momx - meanX); - fixed_t deltay1 = (mobj1->momy - meanY); - fixed_t deltay2 = (mobj2->momy - meanY); - mobj1->momx = meanX + FixedMul(deltax1, a); - mobj1->momy = meanY + FixedMul(deltay1, a); - mobj2->momx = meanX + FixedMul(deltax2, a); - mobj2->momy = meanY + FixedMul(deltay2, a); - } - /* - if (mobj1->player && mobj2->player) // Weight is applicable if both are players - { - fixed_t m1w = 15 + mobj1->player->kartweight; - fixed_t m2w = 15 + mobj2->player->kartweight; - newx = FixedMul(mobj1->momx, FixedDiv(m1w*FRACUNIT, m2w*FRACUNIT)); - newy = FixedMul(mobj1->momy, FixedDiv(m1w*FRACUNIT, m2w*FRACUNIT)); - mobj1->momx = FixedMul(mobj2->momx, FixedDiv(m2w*FRACUNIT, m1w*FRACUNIT)); - mobj1->momy = FixedMul(mobj2->momy, FixedDiv(m2w*FRACUNIT, m1w*FRACUNIT)); - } - else*/ - //{ - newx = mobj1->momx; - newy = mobj1->momy; - mobj1->momx = mobj2->momx; - mobj1->momy = mobj2->momy; - //} - mobj2->momx = newx; - mobj2->momy = newy; + mass1 = mass2 = 1*FRACUNIT; + if (mobj1->player) + mass1 = (1+mobj1->player->kartweight*20)*FRACUNIT; + if (mobj2->player) + mass2 = (1+mobj2->player->kartweight*20)*FRACUNIT; + + // find normalised vector from centre of each mobj + ndistx = mobj1->x - mobj2->x; + ndisty = mobj1->y - mobj2->y; + ndistlength = P_AproxDistance(ndistx, ndisty); + ndistx = FixedDiv(ndistx, ndistlength); + ndisty = FixedDiv(ndisty, ndistlength); + + // find length of the component from the movement along n + a1 = FixedMul(mobj1->momx, ndistx) + FixedMul(mobj1->momy, ndisty); + a2 = FixedMul(mobj2->momx, ndistx) + FixedMul(mobj2->momy, ndisty); + + optimizedP = FixedDiv(FixedMul(2*FRACUNIT, a1 - a2), mass1 + mass2); + + // calculate new movement of mobj1 + mobj1->momx = mobj1->momx - FixedMul(FixedMul(optimizedP, mass2), ndistx); + mobj1->momy = mobj1->momy - FixedMul(FixedMul(optimizedP, mass2), ndisty); + + // calculate new movement of mobj2 + mobj2->momx = mobj2->momx + FixedMul(FixedMul(optimizedP, mass1), ndistx); + mobj2->momy = mobj2->momy + FixedMul(FixedMul(optimizedP, mass1), ndisty); + + // In addition to knocking players based on their momentum into each other + // I will bounce them away from each other based on weight + optimizedP = FixedDiv(cv_collideminimum.value*FRACUNIT, mass1 + mass2); // reuse these variables for helping decide bounce speed + a1 = FixedMul(optimizedP, mass2); + a2 = FixedMul(optimizedP, mass1); + P_Thrust(mobj1, R_PointToAngle2(mobj1->x, mobj1->y, mobj2->x, mobj2->y)+ANGLE_180, a1); + P_Thrust(mobj2, R_PointToAngle2(mobj1->x, mobj1->y, mobj2->x, mobj2->y), a2); + if (bounce == true) // Perform a Goomba Bounce. mobj1->momz = -mobj1->momz; else @@ -1147,60 +1127,22 @@ void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce) mobj1->momz = mobj2->momz; mobj2->momz = newz; } -} void K_KartBouncer(void) { - fixed_t i, j; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) - for (j = 0; j < MAXPLAYERS; j++) - players[i].collide[j] = false; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo) - && !players[i].kartstuff[k_growshrinktimer] - && !players[i].kartstuff[k_squishedtimer] - && !players[i].kartstuff[k_bootaketimer] - && !players[i].kartstuff[k_spinouttimer] - && !players[i].kartstuff[k_startimer]) - { - for (j = i+1; j < MAXPLAYERS; j++) - if (playeringame[j] && players[j].mo && !P_MobjWasRemoved(players[j].mo) - && !players[j].kartstuff[k_squishedtimer] - && !players[j].kartstuff[k_growshrinktimer] - && !players[j].kartstuff[k_bootaketimer] - && !players[j].kartstuff[k_spinouttimer] - && !players[j].kartstuff[k_startimer]) - { - if (players[j].mo == players[i].mo) - break; - if (K_IsTouching(players[i].mo, players[j].mo)) - { - if (!players[i].collide[j] && !players[j].collide[i]) - { - if (P_IsObjectOnGround(players[j].mo) && players[i].mo->momz < 0) - K_SwapMomentum(players[i].mo, players[j].mo, true); - else if (P_IsObjectOnGround(players[i].mo) && players[j].mo->momz < 0) - K_SwapMomentum(players[j].mo, players[i].mo, true); - else - K_SwapMomentum(players[i].mo, players[j].mo, false); + // Because this is done during collision now, rmomx and rmomy need to be recalculated + // so that friction doesn't immediately decide to stop the player if they're at a standstill + if (mobj1->player) + { + mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx; + mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy; + } - if (players[i].kartstuff[k_mushroomtimer] && !(players[j].kartstuff[k_mushroomtimer])) - K_StealBalloon(&players[i], &players[j]); - else if (players[j].kartstuff[k_mushroomtimer] && !(players[i].kartstuff[k_mushroomtimer])) - K_StealBalloon(&players[j], &players[i]); - - players[i].collide[j] = true; - players[j].collide[i] = true; - } - } - else - { - players[i].collide[j] = false; - players[j].collide[i] = false; - } - } - } + if (mobj2->player) + { + mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx; + mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy; + } } /** \brief Checks that the player is on an offroad subsector for realsies diff --git a/src/k_kart.h b/src/k_kart.h index 6eb17fd7..b0ce5b7b 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -15,7 +15,7 @@ UINT8 K_GetKartColorByName(const char *name); void K_RegisterKartStuff(void); -void K_KartBouncer(void); +void K_KartBilliards(mobj_t *mobj1, mobj_t *mobj2, boolean bounce); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_SpinPlayer(player_t *player, mobj_t *source); void K_SquishPlayer(player_t *player, mobj_t *source); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 44a27cd1..06cc69e0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -130,8 +130,6 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->powers, META_POWERS); else if (fastcmp(field,"kartstuff")) LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); - else if (fastcmp(field,"collide")) - LUA_PushUserdata(L, plr->collide, META_COLLIDE); else if (fastcmp(field,"pflags")) lua_pushinteger(L, plr->pflags); else if (fastcmp(field,"panim")) diff --git a/src/lua_script.c b/src/lua_script.c index 9ba7ce7f..aafabbb9 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -435,7 +435,6 @@ void LUA_InvalidatePlayer(player_t *player) LUA_InvalidateUserdata(player); LUA_InvalidateUserdata(player->powers); LUA_InvalidateUserdata(player->kartstuff); - LUA_InvalidateUserdata(player->collide); LUA_InvalidateUserdata(&player->cmd); } diff --git a/src/p_map.c b/src/p_map.c index bf7ad90d..af5cc924 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -320,6 +320,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) } } +#if 0 static void P_DoTailsCarry(player_t *sonic, player_t *tails) { INT32 p; @@ -400,6 +401,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) sonic->pflags &= ~PF_CARRIED; } } +#endif // // PIT_CheckThing @@ -1534,7 +1536,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } // Force solid players in hide and seek to avoid corner stacking. - if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + // Kart: No Tailspickup ever, players are always solid + /*if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) { if (tmthing->player && thing->player) { @@ -1546,7 +1549,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player-players == consoleplayer && botingame) CV_SetValue(&cv_analog2, true); thing->player->pflags &= ~PF_CARRIED; - } + }*/ if (thing->player) { @@ -1592,6 +1595,36 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->z <= thing->z + thing->height) iwassprung = P_DoSpring(thing, tmthing); } + else if (thing->player) // bounce when players collide + { + if (thing->player->kartstuff[k_growshrinktimer] || thing->player->kartstuff[k_squishedtimer] + || thing->player->kartstuff[k_bootaketimer] || thing->player->kartstuff[k_spinouttimer] + || thing->player->kartstuff[k_startimer] || thing->player->kartstuff[k_justbumped] + || tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer] + || tmthing->player->kartstuff[k_bootaketimer] || tmthing->player->kartstuff[k_spinouttimer] + || tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped]) + { + return true; + } + + if (P_IsObjectOnGround(thing) && tmthing->momz < 0) + K_KartBilliards(tmthing, thing, true); + else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) + K_KartBilliards(thing, tmthing, true); + else + K_KartBilliards(tmthing, thing, false); + + if (gametype != GT_RACE) + { + if (thing->player->kartstuff[k_mushroomtimer] && !(tmthing->player->kartstuff[k_mushroomtimer])) + K_StealBalloon(&thing->player, &tmthing->player); + else if (tmthing->player->kartstuff[k_mushroomtimer] && !(thing->player->kartstuff[k_mushroomtimer])) + K_StealBalloon(&tmthing->player, &thing->player); + } + + thing->player->kartstuff[k_justbumped] = 6; + tmthing->player->kartstuff[k_justbumped] = 6; + } // Are you touching the side of the object you're interacting with? else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) diff --git a/src/p_saveg.c b/src/p_saveg.c index e04ee39c..d813337b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -138,8 +138,6 @@ static void P_NetArchivePlayers(void) WRITEUINT16(save_p, players[i].powers[j]); for (j = 0; j < NUMKARTSTUFF; j++) WRITEINT32(save_p, players[i].kartstuff[j]); - for (j = 0; j < MAXPLAYERS; j++) - WRITEUINT8(save_p, players[i].collide[j]); WRITEUINT8(save_p, players[i].playerstate); WRITEUINT32(save_p, players[i].pflags); @@ -321,8 +319,6 @@ static void P_NetUnArchivePlayers(void) players[i].powers[j] = READUINT16(save_p); for (j = 0; j < NUMKARTSTUFF; j++) players[i].kartstuff[j] = READINT32(save_p); - for (j = 0; j < MAXPLAYERS; j++) - players[i].collide[j] = (boolean)READUINT8(save_p); players[i].playerstate = READUINT8(save_p); players[i].pflags = READUINT32(save_p); diff --git a/src/p_tick.c b/src/p_tick.c index 71bd3594..7ea98435 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -625,9 +625,6 @@ void P_Ticker(boolean run) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - // SRB2kart - runs bounce collision for players - K_KartBouncer(); - #ifdef HAVE_BLUA LUAh_ThinkFrame(); #endif @@ -743,9 +740,6 @@ void P_PreTicker(INT32 frames) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - // SRB2kart - runs bounce collision for players - K_KartBouncer(); - #ifdef HAVE_BLUA LUAh_ThinkFrame(); #endif