diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a022e99f..ad8b93e0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -519,6 +519,8 @@ 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] = (UINT16)SHORT(players[i].kartstuff[j]); // SRB2kart + for (j = 0; j < MAXPLAYERS; ++j) + rsp->collide[j] = players[i].collide[j]; // SRB2kart // Score is resynched in the rspfirm resync packet rsp->health = 0; // resynched with mo health @@ -651,6 +653,8 @@ 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] = (UINT16)SHORT(rsp->kartstuff[j]); // SRB2kart + for (j = 0; j < MAXPLAYERS; ++j) + players[i].collide[j] = rsp->collide[j]; // SRB2kart // Score is resynched in the rspfirm resync packet players[i].health = rsp->health; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3072c16c..6de3b348 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -163,6 +163,7 @@ typedef struct UINT16 powers[NUMPOWERS]; INT32 kartstuff[NUMKARTSTUFF]; // SRB2kart + UINT8 collide[MAXPLAYERS]; // SRB2kart // Score is resynched in the confirm resync packet INT32 health; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 24105770..435bbfe4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -318,6 +318,12 @@ consvar_t cv_karthud = {"karthud", "Default", CV_SAVE|CV_CALL, karthud_cons_t, N consvar_t cv_kartcc = {"kartcc", "100cc", CV_NETVAR, kartcc_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t speedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {0, NULL}}; consvar_t cv_speedometer = {"speedometer", "Kilometers", CV_SAVE, speedometer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // use tics in display + +static CV_PossibleValue_t cv_collideminimum_cons_t[] = {{1, "MIN"}, {16384, "MAX"}, {0, NULL}}; +consvar_t cv_collideminimum = {"collide_minspeed", "25", CV_NETVAR, cv_collideminimum_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t cv_collidesoundnum_cons_t[] = {{1, "MIN"}, {1208, "MAX"}, {0, NULL}}; +consvar_t cv_collidesoundnum = {"collide_soundnum", "231", CV_NETVAR, cv_collidesoundnum_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_collidesounds = {"collide_sounds", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; // consvar_t cv_ringslinger = {"ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT, CV_YesNo, diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 6fb524d1..6f50358f 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -107,6 +107,10 @@ extern consvar_t cv_blueshell, cv_jaws, cv_fireflower, cv_tripleredshell, cv_lig extern consvar_t cv_karthud; extern consvar_t cv_kartcc; extern consvar_t cv_speedometer; + +extern consvar_t cv_collideminimum; +extern consvar_t cv_collidesoundnum; +extern consvar_t cv_collidesounds; // extern consvar_t cv_itemfinder; diff --git a/src/d_player.h b/src/d_player.h index b8fb0d78..59516f35 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -364,6 +364,7 @@ typedef struct player_s // SRB2kart stuff INT32 kartstuff[NUMKARTSTUFF]; + boolean collide[MAXPLAYERS]; // Bit flags. // See pflags_t, above. diff --git a/src/doomdef.h b/src/doomdef.h index 5650099e..012e305f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -143,16 +143,16 @@ extern FILE *logstream; #define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 103 // Game version -#define SUBVERSION 3 // more precise version number +#define SUBVERSION 4 // more precise version number #define VERSIONSTRING "Development EXE" -#define VERSIONSTRINGW "v1.3.03" +#define VERSIONSTRINGW "v1.3.04" // most interface strings are ignored in development mode. // we use comprevision and compbranch instead. #else #define VERSION 103 // Game version -#define SUBVERSION 3 // more precise version number -#define VERSIONSTRING "DevEXE v1.3.03" -#define VERSIONSTRINGW L"v1.3.03" +#define SUBVERSION 4 // more precise version number +#define VERSIONSTRING "DevEXE v1.3.04" +#define VERSIONSTRINGW L"v1.3.04" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #endif diff --git a/src/g_game.c b/src/g_game.c index 03b5bc88..465d4d64 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2128,6 +2128,7 @@ 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 791a6f57..59c19511 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -295,6 +295,9 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartcc); CV_RegisterVar(&cv_speedometer); + CV_RegisterVar(&cv_collideminimum); + CV_RegisterVar(&cv_collidesoundnum); + CV_RegisterVar(&cv_collidesounds); } //} @@ -881,6 +884,110 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) //{ SRB2kart p_user.c Stuff +boolean K_IsTouching(mobj_t *mobj1, mobj_t *mobj2) +{ + 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) +{ + if (mobj1 == NULL || mobj2 == NULL) + 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); + } + 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); + } + fixed_t newx = mobj1->momx; + fixed_t newy = mobj1->momy; + fixed_t newz = mobj1->momz; + mobj1->momx = mobj2->momx; + mobj1->momy = mobj2->momy; + mobj2->momx = newx; + mobj2->momy = newy; + if (bounce == true) // Perform a Goomba Bounce. + mobj1->momz = -mobj1->momz; + else + { + 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)) + { + for (j = i+1; j < MAXPLAYERS; j++) + if (playeringame[j] && players[j].mo && !P_MobjWasRemoved(players[j].mo)) + { + 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); + players[i].collide[j] = true; + players[j].collide[i] = true; + } + } + else + { + players[i].collide[j] = false; + players[j].collide[i] = false; + } + } + } +} + /** \brief Checks that the player is on an offroad subsector for realsies \param mo player mobj object @@ -895,7 +1002,10 @@ static boolean K_CheckOffroadCollide(mobj_t *mo) if (((mo->z <= mo->subsector->sector->floorheight && !(mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR)) || (mo->z + mo->height >= mo->subsector->sector->ceilingheight - && (mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING)))) + && (mo->eflags & MFE_VERTICALFLIP) && (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING))) + && (GETSECSPECIAL(mo->subsector->sector->special, 1) == 2 + || GETSECSPECIAL(mo->subsector->sector->special, 1) == 3 + || GETSECSPECIAL(mo->subsector->sector->special, 1) == 4)) return true; return false; @@ -1621,14 +1731,14 @@ static mobj_t *P_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map return mo; } -static void K_DoMagnet(player_t * player) +static void K_DoMagnet(player_t *player) { S_StartSound(player->mo, sfx_s3k45); player->kartstuff[k_magnettimer] = 35; P_NukeEnemies(player->mo, player->mo, 16*FRACUNIT); } -static void K_DoBooSteal(player_t * player) +static void K_DoBooSteal(player_t *player) { INT32 i, numplayers = 0; INT32 playerswappable[MAXPLAYERS]; @@ -1863,8 +1973,8 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) static void K_KartDrift(player_t *player, boolean onground) { - fixed_t dsone = 26*2 + player->kartspeed; - fixed_t dstwo = dsone*2; + fixed_t dsone = 51 + player->kartspeed; // 52 - 60 + fixed_t dstwo = dsone*2; // 104 - 120 // Drifting is actually straffing + automatic turning. // Holding the Jump button will enable drifting. @@ -1891,7 +2001,7 @@ static void K_KartDrift(player_t *player, boolean onground) && player->kartstuff[k_driftcharge] >= dstwo && onground) { - player->kartstuff[k_driftboost] = 40; + player->kartstuff[k_driftboost] = 60; S_StartSound(player->mo, sfx_mush); player->kartstuff[k_driftcharge] = 0; } diff --git a/src/k_kart.h b/src/k_kart.h index 1456ec7c..a7050623 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -15,6 +15,7 @@ UINT8 K_GetKartColorByName(const char *name); void K_RegisterKartStuff(void); +void K_KartBouncer(void); 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_libs.h b/src/lua_libs.h index 4f8b3474..55b2558d 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -31,6 +31,7 @@ extern lua_State *gL; #define META_SKIN "SKIN_T*" #define META_POWERS "PLAYER_T*POWERS" #define META_KARTSTUFF "PLAYER_T*KARTSTUFF" +#define META_COLLIDE "PLAYER_T*COLLIDE" #define META_SOUNDSID "SKIN_T*SOUNDSID" #define META_VERTEX "VERTEX_T*" diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 06cc69e0..44a27cd1 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -130,6 +130,8 @@ 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 b9a6b5f2..42ca0507 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -435,6 +435,7 @@ 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 99f4e188..43a11341 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3500,7 +3500,7 @@ retry: PT_ADDLINES, PTR_SlideTraverse); // Some walls are bouncy even if you're not - if (bestslideline && bestslideline->flags & ML_BOUNCY) + if (bestslideline && !(bestslideline->flags & ML_BOUNCY)) // SRB2kart - All walls are bouncy unless specified otherwise { P_BounceMove(mo); return; diff --git a/src/p_saveg.c b/src/p_saveg.c index d10cbcbc..56250118 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -138,6 +138,8 @@ static void P_NetArchivePlayers(void) WRITEUINT16(save_p, players[i].powers[j]); for (j = 0; j < NUMKARTSTUFF; j++) WRITEUINT16(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); @@ -319,6 +321,8 @@ static void P_NetUnArchivePlayers(void) players[i].powers[j] = READUINT16(save_p); for (j = 0; j < NUMKARTSTUFF; j++) players[i].kartstuff[j] = READUINT16(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_spec.h b/src/p_spec.h index 82473818..ad705727 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -392,9 +392,10 @@ typedef struct UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not } friction_t; -// SRB2kart - TODO: To satisfy Iceman's craving, I'll leave this here: 62914 : Is the number he wants friction to be. // Friction defines. #define ORIG_FRICTION (62914) ///< Original value. +//#define ORIG_FRICTION_RETRO (0xE8 << (FRACBITS-8)) +//#define ORIG_FRICTION_NEO (62914) #define ORIG_FRICTION_FACTOR (8 << (FRACBITS-8)) ///< Original value. void T_Friction(friction_t *f); diff --git a/src/p_tick.c b/src/p_tick.c index f4bc5932..3d59e3ae 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -21,6 +21,7 @@ #include "m_random.h" #include "lua_script.h" #include "lua_hook.h" +#include "k_kart.h" // Object place #include "m_cheat.h" @@ -624,6 +625,9 @@ 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 @@ -737,6 +741,9 @@ 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