diff --git a/src/command.c b/src/command.c index 01a34f3cb..7184ace42 100644 --- a/src/command.c +++ b/src/command.c @@ -110,6 +110,8 @@ CV_PossibleValue_t gpdifficulty_cons_t[] = { {0, NULL} }; +CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; + // Filter consvars by EXECVERSION // First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0) // Also set CV_HIDDEN during runtime, after config is loaded @@ -2260,6 +2262,11 @@ void CV_AddValue(consvar_t *var, INT32 increment) max = KARTSPEED_HARD+1; } } + else if (var->PossibleValue == kartvoices_cons_t + && !M_SecretUnlocked(SECRET_MEMETAUNTS, true)) + { + max--; + } #ifdef PARANOIA if (currentindice == -1) I_Error("CV_AddValue: current value %d not found in possible value\n", diff --git a/src/command.h b/src/command.h index 8ad27bfbc..b3bae86a7 100644 --- a/src/command.h +++ b/src/command.h @@ -176,6 +176,7 @@ extern CV_PossibleValue_t CV_Natural[]; // SRB2kart // the KARTSPEED and KARTGP were previously defined here, but moved to doomstat to avoid circular dependencies extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[]; +extern CV_PossibleValue_t kartvoices_cons_t[]; extern consvar_t cv_execversion; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 37f07b12f..b58334da6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -410,8 +410,8 @@ static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, " consvar_t cv_kartencore = CVAR_INIT ("encore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange); static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}}; consvar_t cv_kartspeedometer = CVAR_INIT ("speedometer", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display -static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; consvar_t cv_kartvoices = CVAR_INIT ("tauntvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL); +consvar_t cv_karthorns = CVAR_INIT ("taunthorns", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL); static CV_PossibleValue_t kartbot_cons_t[] = { {0, "Off"}, diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 93ad42bbf..154c09717 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -86,6 +86,7 @@ extern consvar_t cv_kartfrantic; extern consvar_t cv_kartencore; extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; +extern consvar_t cv_karthorns; extern consvar_t cv_kartbot; extern consvar_t cv_karteliminatelast; extern consvar_t cv_thunderdome; diff --git a/src/d_player.h b/src/d_player.h index 843f31b65..39a25a8fd 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -277,6 +277,7 @@ typedef enum khud_enginesnd, // Engine sound offset this player is using. khud_voices, // Used to stop the player saying more voices than it should khud_tauntvoices, // Used to specifically stop taunt voice spam + khud_taunthorns, // Used to specifically stop taunt horn spam // Battle khud_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics diff --git a/src/deh_soc.c b/src/deh_soc.c index 18ba79861..48f4f6828 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2364,6 +2364,8 @@ void readunlockable(MYFILE *f, INT32 num) unlockables[num].type = SECRET_SOUNDTEST; else if (fastcmp(word2, "ALTTITLE")) unlockables[num].type = SECRET_ALTTITLE; + else if (fastcmp(word2, "MEMETAUNTS")) + unlockables[num].type = SECRET_MEMETAUNTS; else if (fastcmp(word2, "ITEMFINDER")) unlockables[num].type = SECRET_ITEMFINDER; else @@ -3602,7 +3604,7 @@ void readfollower(MYFILE *f) INT32 res; INT32 i; - if (numfollowers >= MAXSKINS) + if (numfollowers >= MAXFOLLOWERS) { I_Error("Out of Followers\nLoad less addons to fix this."); } @@ -3625,6 +3627,7 @@ void readfollower(MYFILE *f) followers[numfollowers].hitconfirmtime = TICRATE; followers[numfollowers].defaultcolor = FOLLOWERCOLOR_MATCH; followers[numfollowers].category = UINT8_MAX; + followers[numfollowers].hornsound = sfx_horn00; strcpy(followers[numfollowers].icon, "MISSING"); do @@ -3710,6 +3713,10 @@ void readfollower(MYFILE *f) deh_warning("Follower %d: unknown follower color '%s'", numfollowers, word2); } } + else if (fastcmp(word, "HORNSOUND")) + { + followers[numfollowers].hornsound = get_number(word2); + } else if (fastcmp(word, "SCALE")) { followers[numfollowers].scale = (fixed_t)get_number(word2); diff --git a/src/deh_tables.c b/src/deh_tables.c index 26b0ae763..9c4b19c88 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3308,6 +3308,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SERVANTHAND", + "S_HORNCODE", + // Signpost sparkles "S_SIGNSPARK1", "S_SIGNSPARK2", @@ -5359,6 +5361,8 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SERVANTHAND", + "MT_HORNCODE", + "MT_SIGNSPARKLE", "MT_FASTLINE", diff --git a/src/info.c b/src/info.c index dcc3c4110..37e2a9034 100644 --- a/src/info.c +++ b/src/info.c @@ -563,6 +563,8 @@ char sprnames[NUMSPRITES + 1][5] = "DHND", // Servant Hand + "HORN", // Horncode + "WIPD", // Wipeout dust trail "DRIF", // Drift Sparks "BDRF", // Brake drift sparks @@ -3980,6 +3982,8 @@ state_t states[NUMSTATES] = {SPR_DHND, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SERVANTHAND + {SPR_HORN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_HORNCODE + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2 {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3 @@ -22840,6 +22844,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, + + { // MT_HORNCODE + -1, // doomednum + S_HORNCODE, // spawnstate + 1000, // 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 + 36*FRACUNIT, // radius + 36*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, { // MT_SIGNSPARKLE -1, // doomednum diff --git a/src/info.h b/src/info.h index 8d3e85031..289bbe438 100644 --- a/src/info.h +++ b/src/info.h @@ -1114,6 +1114,8 @@ typedef enum sprite SPR_DHND, // Servant Hand + SPR_HORN, // Horncode + SPR_WIPD, // Wipeout dust trail SPR_DRIF, // Drift Sparks SPR_BDRF, // Brake drift sparks @@ -4390,6 +4392,8 @@ typedef enum state S_SERVANTHAND, + S_HORNCODE, + // Signpost sparkles S_SIGNSPARK1, S_SIGNSPARK2, @@ -6476,6 +6480,8 @@ typedef enum mobj_type MT_SERVANTHAND, + MT_HORNCODE, + MT_SIGNSPARKLE, MT_FASTLINE, diff --git a/src/k_follower.c b/src/k_follower.c index 937527a49..511e81932 100644 --- a/src/k_follower.c +++ b/src/k_follower.c @@ -11,10 +11,11 @@ #include "r_skins.h" #include "p_local.h" #include "p_mobj.h" +#include "s_sound.h" #include "m_cond.h" INT32 numfollowers = 0; -follower_t followers[MAXSKINS]; +follower_t followers[MAXFOLLOWERS]; INT32 numfollowercategories; followercategory_t followercategories[MAXFOLLOWERCATEGORIES]; @@ -142,6 +143,11 @@ void K_RemoveFollower(player_t *player) bub = tmp; } + // And the honk. + bub = player->follower->hprev; + if (!P_MobjWasRemoved(bub)) + P_RemoveMobj(bub); + P_RemoveMobj(player->follower); P_SetTarget(&player->follower, NULL); } @@ -649,6 +655,50 @@ void K_HandleFollower(player_t *player) { K_UpdateFollowerState(player->follower, fl->idlestate, FOLLOWERSTATE_IDLE); } + + // Horncode + if (P_MobjWasRemoved(player->follower->hprev) == false) + { + mobj_t *honk = player->follower->hprev; + + honk->flags2 &= ~MF2_AMBUSH; + + honk->color = player->skincolor; + + P_MoveOrigin( + honk, + player->follower->x, + player->follower->y, + player->follower->z + player->follower->height + ); + + K_FlipFromObject(honk, player->follower); + + honk->angle = R_PointToAngle2( + player->mo->x, + player->mo->y, + player->follower->x, + player->follower->y + ); + + honk->destscale = (2*player->mo->scale)/3; + + fixed_t offsetamount = 0; + if (honk->fuse > 1) + { + offsetamount = (honk->fuse-1)*honk->destscale/2; + if (leveltime & 1) + offsetamount = -offsetamount; + } + else if (S_SoundPlaying(honk, fl->hornsound)) + { + honk->fuse++; + } + + honk->sprxoff = P_ReturnThrustX(honk, honk->angle, offsetamount); + honk->spryoff = P_ReturnThrustY(honk, honk->angle, offsetamount); + honk->sprzoff = -honk->sprxoff; + } } if (player->mo->hitlag) @@ -658,3 +708,76 @@ void K_HandleFollower(player_t *player) return; } } + +/*-------------------------------------------------- + void K_FollowerHornTaunt(player_t *taunter, player_t *victim) + + See header file for description. +--------------------------------------------------*/ +void K_FollowerHornTaunt(player_t *taunter, player_t *victim) +{ + if ( + (cv_karthorns.value == 0) + || taunter == NULL + || victim == NULL + || taunter->followerskin < 0 + || taunter->followerskin >= numfollowers + || (P_IsLocalPlayer(victim) == false && cv_karthorns.value != 2) + || P_MobjWasRemoved(taunter->mo) == true + || P_MobjWasRemoved(taunter->follower) == true + ) + return; + + const follower_t *fl = &followers[taunter->followerskin]; + + const boolean tasteful = (taunter->karthud[khud_taunthorns] == 0); + + if (tasteful || cv_karthorns.value == 2) + { + mobj_t *honk = taunter->follower->hprev; + const fixed_t desiredscale = (2*taunter->mo->scale)/3; + + if (P_MobjWasRemoved(honk) == true) + { + honk = P_SpawnMobj( + taunter->follower->x, + taunter->follower->y, + taunter->follower->z + taunter->follower->height, + MT_HORNCODE + ); + + if (P_MobjWasRemoved(honk) == true) + return; // Permit lua override of horn production + + P_SetTarget(&taunter->follower->hprev, honk); + P_SetTarget(&honk->target, taunter->follower); + + K_FlipFromObject(honk, taunter->follower); + + honk->color = taunter->skincolor; + + honk->angle = honk->old_angle = R_PointToAngle2( + taunter->mo->x, + taunter->mo->y, + taunter->follower->x, + taunter->follower->y + ); + } + + // Only do for the first activation this tic. + if (!(honk->flags2 & MF2_AMBUSH)) + { + honk->destscale = desiredscale; + + P_SetScale(honk, (11*desiredscale)/10); + honk->fuse = TICRATE/2; + honk->renderflags |= RF_DONTDRAW; + + S_StartSound(taunter->follower, fl->hornsound); + + honk->flags2 |= MF2_AMBUSH; + } + + honk->renderflags &= ~K_GetPlayerDontDrawFlag(victim); + } +} diff --git a/src/k_follower.h b/src/k_follower.h index d01939040..9da3d4e73 100644 --- a/src/k_follower.h +++ b/src/k_follower.h @@ -20,6 +20,13 @@ extern "C" { #endif +// The important collorary to "Hornmod is universally hated in dev" is +// the simple phrase "this is why" -- 1024 is obscene yet will fill up. +// By the way, this comment will grow stronger and stronger every time +// somebody comes here to double it, so I encourage you to leave a new +// (dated) comment every time you do so. ~toast 280623 +#define MAXFOLLOWERS 1024 + #define FOLLOWERCOLOR_MATCH UINT16_MAX #define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1) @@ -85,12 +92,14 @@ struct follower_t statenum_t losestate; // state when the player has lost statenum_t hitconfirmstate; // state for hit confirm tic_t hitconfirmtime; // time to keep the above playing for + + sfxenum_t hornsound; // Press (B) to announce you are pressing (B) }; extern INT32 numfollowers; -extern follower_t followers[MAXSKINS]; +extern follower_t followers[MAXFOLLOWERS]; -#define MAXFOLLOWERCATEGORIES 32 +#define MAXFOLLOWERCATEGORIES 64 struct followercategory_t { @@ -217,6 +226,21 @@ void K_HandleFollower(player_t *player); void K_RemoveFollower(player_t *player); +/*-------------------------------------------------- + void K_FollowerHornTaunt(player_t *taunter, player_t *victim) + + Plays horn and spawns object (MOSTLY non-netsynced) + + Input Arguments:- + taunter - Source player with a follower + victim - Player that hears and sees the honk + + Return:- + None +--------------------------------------------------*/ + +void K_FollowerHornTaunt(player_t *taunter, player_t *victim); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/k_kart.c b/src/k_kart.c index 2adcfa4ea..ed58a5b19 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -359,6 +359,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartencore); CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_kartvoices); + CV_RegisterVar(&cv_karthorns); CV_RegisterVar(&cv_kartbot); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_thunderdome); @@ -2055,13 +2056,29 @@ void K_SpawnMagicianParticles(mobj_t *mo, int spread) } } -static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) +static SINT8 K_GlanceAtPlayers(player_t *glancePlayer, boolean horn) { const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); const angle_t blindSpotSize = ANG10; // ANG5 UINT8 i; SINT8 glanceDir = 0; SINT8 lastValidGlance = 0; + boolean podiumspecial = (K_PodiumSequence() == true && glancePlayer->nextwaypoint == NULL && glancePlayer->speed == 0); + + if (podiumspecial) + { + if (glancePlayer->position > 3) + { + // Loser valley, focused on the mountain. + return 0; + } + + if (glancePlayer->position == 1) + { + // Sitting on the stand, I ammm thebest! + return 0; + } + } // See if there's any players coming up behind us. // If so, your character will glance at 'em. @@ -2099,9 +2116,17 @@ static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) continue; } - distance = R_PointToDist2(glancePlayer->mo->x, glancePlayer->mo->y, p->mo->x, p->mo->y); + if (!podiumspecial) + { + distance = R_PointToDist2(glancePlayer->mo->x, glancePlayer->mo->y, p->mo->x, p->mo->y); - if (distance > maxdistance) + if (distance > maxdistance) + { + // Too far away + continue; + } + } + else if (p->position >= glancePlayer->position) { continue; } @@ -2115,7 +2140,7 @@ static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) dir = -dir; } - if (diff > ANGLE_90) + if (diff > (podiumspecial ? (ANGLE_180 - blindSpotSize) : ANGLE_90)) { // Not behind the player continue; @@ -2127,16 +2152,33 @@ static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) continue; } - if (P_CheckSight(glancePlayer->mo, p->mo) == true) + if (!podiumspecial && P_CheckSight(glancePlayer->mo, p->mo) == false) { - // Not blocked by a wall, we can glance at 'em! - // Adds, so that if there's more targets on one of your sides, it'll glance on that side. - glanceDir += dir; - - // That poses a limitation if there's an equal number of targets on both sides... - // In that case, we'll pick the last chosen glance direction. - lastValidGlance = dir; + // Blocked by a wall, we can't glance at 'em! + continue; } + + // Adds, so that if there's more targets on one of your sides, it'll glance on that side. + glanceDir += dir; + + // That poses a limitation if there's an equal number of targets on both sides... + // In that case, we'll pick the last chosen glance direction. + lastValidGlance = dir; + + if (horn == true) + { + K_FollowerHornTaunt(glancePlayer, p); + } + } + + if (horn == true && lastValidGlance != 0) + { + const boolean tasteful = (glancePlayer->karthud[khud_taunthorns] == 0); + + K_FollowerHornTaunt(glancePlayer, glancePlayer); + + if (tasteful && glancePlayer->karthud[khud_taunthorns] < 2*TICRATE) + glancePlayer->karthud[khud_taunthorns] = 2*TICRATE; } if (glanceDir > 0) @@ -2215,7 +2257,8 @@ void K_KartMoveAnimation(player_t *player) { // Only try glancing if you're driving straight. // This avoids all-players loops when we don't need it. - destGlanceDir = K_GlanceAtPlayers(player); + const boolean horn = lookback && !(player->pflags & PF_GAINAX); + destGlanceDir = K_GlanceAtPlayers(player, horn); if (lookback == true) { @@ -2649,7 +2692,9 @@ void K_TryHurtSoundExchange(mobj_t *victim, mobj_t *attacker) attacker->player->confirmVictim = (victim->player - players); attacker->player->confirmVictimDelay = TICRATE/2; - if (attacker->player->follower != NULL) + if (attacker->player->follower != NULL + && attacker->player->followerskin >= 0 + && attacker->player->followerskin < numfollowers) { const follower_t *fl = &followers[attacker->player->followerskin]; attacker->player->follower->movecount = fl->hitconfirmtime; // movecount is used to play the hitconfirm animation for followers. @@ -7415,6 +7460,9 @@ void K_KartPlayerHUDUpdate(player_t *player) if (player->karthud[khud_tauntvoices]) player->karthud[khud_tauntvoices]--; + if (player->karthud[khud_taunthorns]) + player->karthud[khud_taunthorns]--; + if (player->karthud[khud_trickcool]) player->karthud[khud_trickcool]--; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 98696d5cc..152629e7f 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -5073,6 +5073,9 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili case SECRET_CUP: categoryid = '4'; break; + case SECRET_MAP: + categoryid = '8'; + break; case SECRET_HARDSPEED: case SECRET_MASTERMODE: case SECRET_ENCORE: @@ -5081,8 +5084,9 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili case SECRET_ONLINE: case SECRET_ADDONS: case SECRET_EGGTV: - case SECRET_ALTTITLE: case SECRET_SOUNDTEST: + case SECRET_ALTTITLE: + case SECRET_MEMETAUNTS: categoryid = '6'; break; case SECRET_TIMEATTACK: @@ -5146,10 +5150,14 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili { colormap = R_GetTranslationColormap(TC_DEFAULT, colorid, GTC_MENUCACHE); } - iconid = 0; + iconid = 2; break; } + case SECRET_MAP: + iconid = 14; + break; + case SECRET_HARDSPEED: iconid = 3; break; @@ -5169,11 +5177,14 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili case SECRET_EGGTV: iconid = 11; break; + case SECRET_SOUNDTEST: + iconid = 1; + break; case SECRET_ALTTITLE: iconid = 6; break; - case SECRET_SOUNDTEST: - iconid = 1; + case SECRET_MEMETAUNTS: + iconid = 13; break; case SECRET_TIMEATTACK: @@ -5186,7 +5197,7 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili iconid = 9; break; case SECRET_SPBATTACK: - iconid = 0; // TEMPORARY + iconid = 15; break; default: diff --git a/src/m_cond.h b/src/m_cond.h index 4a2a93ba0..6ca875ab5 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -203,6 +203,7 @@ typedef enum SECRET_EGGTV, // Permit replay playback menu SECRET_SOUNDTEST, // Permit Sound Test SECRET_ALTTITLE, // Permit alternate titlescreen + SECRET_MEMETAUNTS, // Permit "Meme" for kartvoices_cons_t // Assist restrictions SECRET_ITEMFINDER, // Permit locating in-level secrets diff --git a/src/p_saveg.c b/src/p_saveg.c index 8806af267..6fea134e7 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2466,6 +2466,31 @@ static UINT32 SaveSlope(const pslope_t *slope) return 0xFFFFFFFF; } +static boolean TypeIsNetSynced(mobjtype_t type) +{ + // Ignore stationary hoops - these will be respawned from mapthings. + if (type == MT_HOOP) + return false; + + // These are NEVER saved. + if (type == MT_HOOPCOLLIDE) + return false; + + // This hoop has already been collected. + if (type == MT_HOOPCENTER)// && mobj->threshold == 4242) + return false; + + // MT_SPARK: used for debug stuff + if (type == MT_SPARK) + return false; + + // MT_HORNCODE: So it turns out hornmod is fundamentally incompatible with netsync + if (type == MT_HORNCODE) + return false; + + return true; +} + static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; @@ -2473,20 +2498,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 UINT32 diff2; size_t j; - // Ignore stationary hoops - these will be respawned from mapthings. - if (mobj->type == MT_HOOP) - return; - - // These are NEVER saved. - if (mobj->type == MT_HOOPCOLLIDE) - return; - - // This hoop has already been collected. - if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242) - return; - - // MT_SPARK: used for debug stuff - if (mobj->type == MT_SPARK) + if (TypeIsNetSynced(mobj->type) == false) return; diff2 = 0; @@ -5117,9 +5129,7 @@ static void P_RelinkPointers(void) mobj = (mobj_t *)currentthinker; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER - // MT_SPARK: used for debug stuff - || mobj->type == MT_SPARK) + if (TypeIsNetSynced(mobj->type) == false) continue; if (mobj->tracer) @@ -6042,9 +6052,7 @@ void P_SaveNetGame(savebuffer_t *save, boolean resending) continue; mobj = (mobj_t *)th; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER - // MT_SPARK: used for debug stuff - || mobj->type == MT_SPARK) + if (TypeIsNetSynced(mobj->type) == false) continue; mobj->mobjnum = i++; } diff --git a/src/sounds.c b/src/sounds.c index 3accd6b79..61003c11d 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1183,8 +1183,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"clawk1", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND {"clawk2", false, 64, 16, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // SF_X8AWAYSOUND - {"monch", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"etexpl", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Game crash"}, + {"horn00", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"}, // HORNCODE + {"monch", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"etexpl", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Game crash"}, {"iwhp", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Instawhip attack {"gbrk", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Guard break! diff --git a/src/sounds.h b/src/sounds.h index 033728e37..5c2aea153 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1252,6 +1252,7 @@ typedef enum sfx_clawk1, sfx_clawk2, + sfx_horn00, sfx_monch, sfx_etexpl,