diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index b74241a9a..df1f2043e 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -2409,6 +2409,8 @@ bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) { ACSVM::MapScope *map = thread->scopeMap; + ACSVM::String *tuneStr = nullptr; + const char *tune = nullptr; // 0: str tune - id for the tune to play // 1: str song - lump name for the song to map to @@ -2418,6 +2420,15 @@ bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:: { return false; } + + tuneStr = map->getString(argV[0]); + tune = tuneStr->str; + + // Do not allow ACS to remap Stereo Mode tunes. + if (strncmp("stere", tune, 5)) + { + return false; + } Music_Remap(map->getString(argV[0])->str, map->getString(argV[1])->str); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7d3fbfe60..9a8351646 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2729,6 +2729,19 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) K_CheckBumpers(); P_CheckRacers(); + + // Reset map headers' justPlayed and anger records + // when there are no players in a dedicated server. + // Otherwise maps get angry at newly-joined players + // that don't deserve it. + if (dedicated && D_NumPlayers() == 0) + { + for (INT32 i = 0; i < nummapheaders; i++) + { + mapheaderinfo[i]->justPlayed = 0; + mapheaderinfo[i]->anger = 0; + } + } } void CL_Reset(void) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0dc1576d1..fe9cb5e7a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -6090,7 +6090,7 @@ static void Got_Cheat(const UINT8 **cp, INT32 playernum) K_StopRoulette(&player->itemRoulette); player->itemtype = item; - player->itemamount = amt; + K_SetPlayerItemAmount(player, amt); if (amt == 0) { diff --git a/src/g_game.c b/src/g_game.c index fff406bdb..f3411f8e8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2685,7 +2685,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) // SRB2kart p->itemtype = itemtype; - p->itemamount = itemamount; + K_SetPlayerItemAmount(p, itemamount); p->growshrinktimer = growshrinktimer; p->karmadelay = 0; p->eggmanblame = -1; @@ -4064,12 +4064,91 @@ UINT16 G_RandMap(UINT32 tolflags, UINT16 pprevmap, boolean ignoreBuffers, boolea void G_AddMapToBuffer(UINT16 map) { +#if 0 + // DEBUG: make nearly everything but four race levels full justPlayed + // to look into what happens when a dedicated runs for seven million years. + INT32 justplayedvalue = TOLMaps(gametype) - VOTE_NUM_LEVELS; + UINT32 tolflag = G_TOLFlag(gametype); + + // Find all the maps that are ok + INT32 i; + for (i = 0; i < nummapheaders; i++) + { + if (mapheaderinfo[i] == NULL) + { + continue; + } + + if (mapheaderinfo[i]->lumpnum == LUMPERROR) + { + continue; + } + + if ((mapheaderinfo[i]->typeoflevel & tolflag) == 0) + { + continue; + } + + if (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU) + { + // Don't include hidden + continue; + } + + // Only care about restrictions if the host is a listen server. + if (!dedicated) + { + if (!(mapheaderinfo[i]->menuflags & LF2_NOVISITNEEDED) + && !(mapheaderinfo[i]->records.mapvisited & MV_VISITED) + && !( + mapheaderinfo[i]->cup + && mapheaderinfo[i]->cup->cachedlevels[0] == i + )) + { + // Not visited OR head of cup + continue; + } + + if ((mapheaderinfo[i]->menuflags & LF2_FINISHNEEDED) + && !(mapheaderinfo[i]->records.mapvisited & MV_BEATEN)) + { + // Not completed + continue; + } + } + + if (M_MapLocked(i + 1) == true) + { + // We haven't earned this one. + continue; + } + + mapheaderinfo[i]->justPlayed = justplayedvalue; + justplayedvalue -= 1; + if (justplayedvalue <= 0) + break; + } +#else + if (dedicated && D_NumPlayers() == 0) + return; + + const size_t upperJustPlayedLimit = TOLMaps(gametype) - VOTE_NUM_LEVELS - 1; + if (mapheaderinfo[map]->justPlayed == 0) // Started playing a new map. { // Decrement every maps' justPlayed value. INT32 i; for (i = 0; i < nummapheaders; i++) { + // If the map's justPlayed value is higher + // than what it should be, clamp it. + // (Usually a result of SOC files + // manipulating which levels are hidden.) + if (mapheaderinfo[i]->justPlayed > upperJustPlayedLimit) + { + mapheaderinfo[i]->justPlayed = upperJustPlayedLimit; + } + if (mapheaderinfo[i]->justPlayed > 0) { mapheaderinfo[i]->justPlayed--; @@ -4078,8 +4157,9 @@ void G_AddMapToBuffer(UINT16 map) } // Set our map's justPlayed value. - mapheaderinfo[map]->justPlayed = TOLMaps(gametype) - VOTE_NUM_LEVELS; + mapheaderinfo[map]->justPlayed = upperJustPlayedLimit; mapheaderinfo[map]->anger = 0; // Reset voting anger now that we're playing it +#endif } // @@ -5135,6 +5215,9 @@ static void G_DoContinued(void) // when something new is added. void G_EndGame(void) { + // Clean up ACS music remaps. + Music_TuneReset(); + // Handle voting if (nextmap == NEXTMAP_VOTING) { diff --git a/src/k_kart.c b/src/k_kart.c index cc4c14214..01c920c5f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -72,6 +72,28 @@ // comeback is Battle Mode's karma comeback, also bool // mapreset is set when enough players fill an empty server +UINT8 K_SetPlayerItemAmount(player_t *player, UINT8 amount) +{ + player->itemamount = max(min(UINT8_MAX, amount), 0); + return player->itemamount; +} + +UINT8 K_SetPlayerBackupItemAmount(player_t *player, UINT8 amount) +{ + player->backupitemamount = max(min(UINT8_MAX, amount), 0); + return player->backupitemamount; +} + +UINT8 K_AdjustPlayerItemAmount(player_t *player, SINT8 amount) +{ + return K_SetPlayerItemAmount(player, player->itemamount + amount); +} + +UINT8 K_AdjustPlayerBackupItemAmount(player_t *player, SINT8 amount) +{ + return K_SetPlayerBackupItemAmount(player, player->backupitemamount + amount); +} + void K_PopBubbleShield(player_t *player) { if (player->curshield != KSHIELD_BUBBLE) @@ -81,7 +103,7 @@ void K_PopBubbleShield(player_t *player) player->curshield = KSHIELD_NONE; player->itemtype = 0; - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->itemflags &= ~(IF_ITEMOUT|IF_EGGMANOUT); K_AddHitLag(player->mo, 4, false); @@ -7701,7 +7723,7 @@ void K_PuntMine(mobj_t *origMine, mobj_t *punter) if (mineOwner->player->itemamount) { - mineOwner->player->itemamount--; + K_AdjustPlayerItemAmount(mineOwner->player, -1); } if (!mineOwner->player->itemamount) @@ -8271,7 +8293,7 @@ void K_PopPlayerShield(player_t *player) player->curshield = KSHIELD_NONE; player->itemtype = KITEM_NONE; - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); K_UnsetItemOut(player); } @@ -8519,9 +8541,9 @@ void K_DropHnextList(player_t *player) player->itemflags &= ~IF_EGGMANOUT; } else if ((player->itemflags & IF_ITEMOUT) - && (dropall || (--player->itemamount <= 0))) + && (dropall || (K_AdjustPlayerItemAmount(player, -1) <= 0))) { - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); K_UnsetItemOut(player); player->itemtype = KITEM_NONE; } @@ -8776,7 +8798,7 @@ void K_RepairOrbitChain(mobj_t *orbit) } if (orbit->target && !P_MobjWasRemoved(orbit->target) && orbit->target->player->itemamount != num) - orbit->target->player->itemamount = num; + K_SetPlayerItemAmount(orbit->target->player, num); } } @@ -8929,7 +8951,7 @@ static void K_MoveHeldObjects(player_t *player) } else if (player->itemflags & IF_ITEMOUT) { - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); K_UnsetItemOut(player); player->itemtype = KITEM_NONE; } @@ -8948,7 +8970,7 @@ static void K_MoveHeldObjects(player_t *player) } else if (player->itemflags & IF_ITEMOUT) { - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); K_UnsetItemOut(player); player->itemtype = KITEM_NONE; } @@ -9174,12 +9196,12 @@ static void K_MoveHeldObjects(player_t *player) // If we can move our backup item into main slots, do so. static void K_TryMoveBackupItem(player_t *player) { - if (player->itemtype && player->itemtype == player->backupitemtype) + if (player->itemtype && player->itemtype == player->backupitemtype && !(player->itemflags & IF_ITEMOUT)) { - player->itemamount += player->backupitemamount; + K_AdjustPlayerItemAmount(player, player->backupitemamount); player->backupitemtype = 0; - player->backupitemamount = 0; + K_SetPlayerBackupItemAmount(player, 0); S_StartSound(player->mo, sfx_mbs54); } @@ -9187,10 +9209,10 @@ static void K_TryMoveBackupItem(player_t *player) if (player->itemtype == KITEM_NONE && player->backupitemtype && P_CanPickupItem(player, PICKUP_PAPERITEM)) { player->itemtype = player->backupitemtype; - player->itemamount = player->backupitemamount; + K_SetPlayerItemAmount(player, player->backupitemamount); player->backupitemtype = 0; - player->backupitemamount = 0; + K_SetPlayerBackupItemAmount(player, 0); S_StartSound(player->mo, sfx_mbs54); } @@ -10415,7 +10437,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { player->rings = 0; player->itemtype = 0; - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->itemRoulette.active = false; } } @@ -10964,7 +10986,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_DeleteHnextList(player); K_DropItems(player); - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->itemtype = 0; player->rocketsneakertimer = 0; @@ -10972,7 +10994,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->itemamount) { K_DropPaperItem(player, player->itemtype, player->itemamount); - player->itemtype = player->itemamount = 0; + player->itemtype = K_SetPlayerItemAmount(player, 0); } */ @@ -11619,7 +11641,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // activate a mine while you're out of its radius, // the SAME tic it sets your itemamount to 0 // ...:dumbestass: - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_PlayAttackTaunt(player->mo); player->botvars.itemconfirm = 0; } @@ -13702,11 +13724,11 @@ void K_StripItems(player_t *player) K_DropRocketSneaker(player); K_DropKitchenSink(player); player->itemtype = KITEM_NONE; - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->itemflags &= ~(IF_ITEMOUT|IF_EGGMANOUT); player->backupitemtype = KITEM_NONE; - player->backupitemamount = 0; + K_SetPlayerBackupItemAmount(player, 0); if (player->itemRoulette.eggman == false) { @@ -15279,7 +15301,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { K_DoSneaker(player, 1); K_PlayBoostTaunt(player->mo); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->botvars.itemconfirm = 0; } break; @@ -15297,7 +15319,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //K_DoSneaker(player, 2); player->rocketsneakertimer = (itemtime*3); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_UpdateHnextList(player, true); for (moloop = 0; moloop < 2; moloop++) @@ -15328,7 +15350,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) max(7u * TICRATE + behindScaled, player->invincibilitytimer + 5u*TICRATE)); K_PlayPowerGloatSound(player->mo); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->botvars.itemconfirm = 0; } break; @@ -15348,7 +15370,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BANANA_SHIELD); if (!mo) { - player->itemamount = moloop; + K_SetPlayerItemAmount(player, moloop); break; } mo->flags |= MF_NOCLIPTHING; @@ -15365,7 +15387,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Banana x3 thrown { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_ThrowKartItem(player, false, MT_BANANA, -1, 0, 0); K_PlayAttackTaunt(player->mo); K_UpdateHnextList(player, false); @@ -15376,7 +15398,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { mobj_t *mo; - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->itemflags |= IF_EGGMANOUT; S_StartSound(player->mo, sfx_s254); mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EGGMANITEM_SHIELD); @@ -15412,7 +15434,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ORBINAUT_SHIELD); if (!mo) { - player->itemamount = moloop; + K_SetPlayerItemAmount(player, moloop); break; } mo->flags |= MF_NOCLIPTHING; @@ -15431,7 +15453,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Orbinaut x3 thrown { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0, 0); K_PlayAttackTaunt(player->mo); K_UpdateHnextList(player, false); @@ -15456,7 +15478,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_JAWZ_SHIELD); if (!mo) { - player->itemamount = moloop; + K_SetPlayerItemAmount(player, moloop); break; } mo->flags |= MF_NOCLIPTHING; @@ -15474,7 +15496,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Jawz thrown { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0); K_PlayAttackTaunt(player->mo); K_UpdateHnextList(player, false); @@ -15502,7 +15524,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_ThrowKartItem(player, false, MT_SSMINE, 1, 1, 0); K_PlayAttackTaunt(player->mo); player->itemflags &= ~IF_ITEMOUT; @@ -15513,7 +15535,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_LANDMINE: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); if (player->throwdir > 0) { K_ThrowKartItem(player, true, MT_LANDMINE, -1, 0, 0); @@ -15548,7 +15570,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); mobj_t *drop = K_ThrowKartItem(player, (player->throwdir > 0), MT_DROPTARGET, -1, 0, 0); P_SetTarget(&drop->tracer, player->mo); K_PlayAttackTaunt(player->mo); @@ -15646,8 +15668,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetObjectMomZ(player->mo, -50*FRACUNIT, true); } */ - - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->botvars.itemconfirm = 0; player->ballhogcharge = 0; player->ballhogburst = 0; @@ -15662,8 +15683,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (numhogs > 0) // no tapfire scams { K_SetItemOut(player); // need this to set itemscale - - player->itemamount -= numhogs; + K_AdjustPlayerItemAmount(player, -numhogs); K_PlayAttackTaunt(player->mo); K_DoBallhogAttack(player, numhogs); @@ -15693,7 +15713,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_SPB: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_SetItemOut(player); K_ThrowKartItem(player, true, MT_SPB, 1, 0, 0); K_UnsetItemOut(player); @@ -15733,7 +15753,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) S_StartSound(player->mo, sfx_kc5a); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->botvars.itemconfirm = 0; } break; @@ -15741,7 +15761,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { K_DoShrink(player); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_PlayPowerGloatSound(player->mo); player->botvars.itemconfirm = 0; } @@ -15856,7 +15876,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->bubbleblowup > bubbletime*2) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); if (player->throwdir == -1) { @@ -15962,7 +15982,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->flamemeter = 0; player->flamelength = 0; player->itemflags &= ~IF_HOLDREADY; - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); } } else @@ -15996,7 +16016,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_HYUDORO: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); //K_DoHyudoroSteal(player); // yes. yes they do. Obj_HyudoroDeploy(player->mo); K_PlayAttackTaunt(player->mo); @@ -16009,7 +16029,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_PlayBoostTaunt(player->mo); //K_DoPogoSpring(player->mo, 32<mo, 0, 0, 0, MT_POGOSPRING); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->botvars.itemconfirm = 0; } break; @@ -16052,7 +16072,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // player->strongdriftboost += TICRATE; // player->driftboost += TICRATE; K_AwardPlayerRings(player, 20*player->itemamount, true); - player->itemamount = 0; + K_SetPlayerItemAmount(player, 0); player->botvars.itemconfirm = 0; } break; @@ -16077,7 +16097,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_ThrowKartItem(player, false, MT_SINK, 1, 2, 0); K_PlayAttackTaunt(player->mo); player->itemflags &= ~IF_ITEMOUT; @@ -16088,7 +16108,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_GACHABOM: if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) { - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_SetItemOut(player); // need this to set itemscale K_ThrowKartItem(player, true, MT_GACHABOM, 0, 0, 0); K_UnsetItemOut(player); @@ -16126,7 +16146,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_UnsetItemOut(player); } - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_PlayAttackTaunt(player->mo); K_UpdateHnextList(player, false); player->botvars.itemconfirm = 0; @@ -16142,7 +16162,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_UnsetItemOut(player); - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); K_PlayAttackTaunt(player->mo); player->botvars.itemconfirm = 0; } @@ -16152,7 +16172,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) && !player->sadtimer) { player->sadtimer = stealtime; - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); player->botvars.itemconfirm = 0; } break; @@ -17568,20 +17588,20 @@ static boolean K_PickUp(player_t *player, mobj_t *picked) if (player->itemtype == type && player->itemamount && !(player->itemflags & IF_ITEMOUT)) { // We have this item in main slot but not deployed, just add it - player->itemamount += amount; + K_SetPlayerItemAmount(player, player->itemamount + amount); } else if (player->backupitemamount && player->backupitemtype) { // We already have a backup item, stack it if it can be stacked or discard it if (player->backupitemtype == type) { - player->backupitemamount += amount; + K_AdjustPlayerBackupItemAmount(player, amount); } else { K_DropPaperItem(player, player->backupitemtype, player->backupitemamount); player->backupitemtype = type; - player->backupitemamount = amount; + K_SetPlayerBackupItemAmount(player, amount); S_StartSound(player->mo, sfx_kc65); } } @@ -17589,7 +17609,7 @@ static boolean K_PickUp(player_t *player, mobj_t *picked) { // We have no backup item, load one up player->backupitemtype = type; - player->backupitemamount = amount; + K_SetPlayerBackupItemAmount(player, amount); } S_StartSound(player->mo, sfx_aple); diff --git a/src/k_kart.h b/src/k_kart.h index e9234555d..8dbc7f5fe 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -125,6 +125,11 @@ Make sure this matches the actual number of states #define AUTORESPAWN_TIME (10*TICRATE) #define AUTORESPAWN_THRESHOLD (7*TICRATE) +UINT8 K_SetPlayerItemAmount(player_t *player, UINT8 amount); +UINT8 K_SetPlayerBackupItemAmount(player_t *player, UINT8 amount); +UINT8 K_AdjustPlayerItemAmount(player_t *player, SINT8 amount); +UINT8 K_AdjustPlayerBackupItemAmount(player_t *player, SINT8 amount); + angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); void K_PopBubbleShield(player_t *player); diff --git a/src/k_roulette.c b/src/k_roulette.c index d410b3e68..45ac3acfa 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -1956,7 +1956,8 @@ void K_KartGetItemResult(player_t *const player, kartitems_t getitem) UINT8 itemamount = K_ItemResultToAmount(getitem, &player->itemRoulette); if (cv_kartdebugitem.value != KITEM_NONE && cv_kartdebugitem.value == player->itemtype && cv_kartdebugamount.value > 1) itemamount = cv_kartdebugamount.value; - player->itemamount = itemamount; + + K_SetPlayerItemAmount(player, itemamount); if (player->itemtype == KITEM_SPB) Obj_SPBEradicateCapsules(); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b34f5bcae..102dde47d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -480,6 +480,12 @@ static int lib_mMusicRemap(lua_State *L) { return LUA_ErrNoTune(L, tune_id); } + + // Do not allow Lua to remap Stereo Mode tunes. + if (strncmp("stere", tune_id, 5)) + { + return LUA_ErrStereo(L, tune_id); + } Music_Remap(tune_id, music_name); diff --git a/src/lua_script.h b/src/lua_script.h index 28f0fecad..41da2591f 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -117,6 +117,9 @@ void COM_Lua_f(void); // Music: "No tune" error. #define LUA_ErrNoTune(L, tune) luaL_error(L, "tune \"%s\" does not exist", tune) +// Music: "Stereo Mode" error. +#define LUA_ErrStereo(L, tune) luaL_error(L, "tune \"%s\" cannot be remapped (stereo mode)", tune) + // Deprecation warnings // Shows once upon use. Then doesn't show again. #define LUA_Deprecated(L,this_func,use_instead)\ diff --git a/src/music.cpp b/src/music.cpp index b50dfaf66..2213842f9 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -25,6 +25,7 @@ TuneManager g_tunes; void Music_Init(void) { + // Many tunes below now have their default songs set in Music_TuneReset. Check there first for changing those. { Tune& tune = g_tunes.insert("level"); @@ -55,21 +56,21 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("battle_overtime", g_tunes.find("level")); - tune.song = "shwdwn"; + tune.song = ""; // Music_TuneReset tune.priority = 11; } { Tune& tune = g_tunes.insert("battle_overtime_stress", g_tunes.find("battle_overtime")); - tune.song = "shwdn2"; + tune.song = ""; // Music_TuneReset tune.priority = 10; } { Tune& tune = g_tunes.insert("grow"); - tune.song = "kgrow"; + tune.song = ""; // Music_TuneReset tune.priority = 20; tune.resume_fade_in = 200; tune.use_level_volume = true; @@ -78,7 +79,7 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("invinc"); - tune.song = "kinvnc"; + tune.song = ""; // Music_TuneReset tune.priority = 21; tune.use_level_volume = true; } @@ -86,7 +87,7 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("finish_silence"); - tune.song = ""; + tune.song = ""; // Music_TuneReset tune.priority = 30; } @@ -100,7 +101,7 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("comeon"); - tune.song = "chalng"; + tune.song = ""; // Music_TuneReset tune.priority = 35; tune.loop = false; } @@ -116,7 +117,7 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("vote"); - tune.song = "vote"; + tune.song = ""; // Music_TuneReset tune.priority = 50; tune.credit = true; } @@ -124,14 +125,14 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("vote_suspense"); - tune.song = "voteea"; + tune.song = ""; // Music_TuneReset tune.priority = 51; } { Tune& tune = g_tunes.insert("vote_end"); - tune.song = "voteeb"; + tune.song = ""; // Music_TuneReset tune.priority = 52; tune.loop = false; } @@ -139,14 +140,14 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("wait"); - tune.song = "WAIT2J"; + tune.song = ""; // Music_TuneReset tune.priority = 60; } { Tune& tune = g_tunes.insert("title"); - tune.song = "_title"; + tune.song = ""; // Music_TuneReset tune.priority = 100; tune.resist = true; } @@ -167,7 +168,7 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("credits_silence"); - tune.song = ""; + tune.song = ""; // Music_TuneReset tune.priority = 100; } @@ -175,7 +176,7 @@ void Music_Init(void) Tune& tune = g_tunes.insert("credits"); tune.priority = 101; - tune.song = "_creds"; + tune.song = ""; // Music_TuneReset tune.credit = true; } @@ -213,10 +214,12 @@ void Music_Init(void) { Tune& tune = g_tunes.insert("lawyer"); - tune.song = "lawyer"; + tune.song = ""; // Music_TuneReset tune.priority = 35; tune.loop = false; } + + Music_TuneReset(); } @@ -522,3 +525,21 @@ void Music_ResetLevelVolume(void) { g_tunes.level_volume(100, true); } + +void Music_TuneReset(void) +{ + Music_Remap("battle_overtime", "shwdwn"); + Music_Remap("battle_overtime_stress", "shwdn2"); + Music_Remap("grow", "kgrow"); + Music_Remap("invinc", "kinvnc"); + Music_Remap("finish_silence", ""); + Music_Remap("comeon", "chalng"); + Music_Remap("vote", "vote"); + Music_Remap("vote_suspense", "voteea"); + Music_Remap("vote_end", "voteeb"); + Music_Remap("wait", "WAIT2J"); + Music_Remap("title", "_title"); + Music_Remap("credits_silence", ""); + Music_Remap("credits", "_creds"); + Music_Remap("lawyer", "lawyer"); +} diff --git a/src/music.h b/src/music.h index 630c7a98c..950016d4c 100644 --- a/src/music.h +++ b/src/music.h @@ -207,6 +207,10 @@ void Music_Tick(void); // the music plays again when re-enabled. void Music_Flip(void); +// Resets all non-dynamic tunes to default values. +// Keeps ACS music remapping from playing havoc after a map. +void Music_TuneReset(void); + #ifdef __cplusplus } // extern "C" diff --git a/src/objects/gachabom-rebound.cpp b/src/objects/gachabom-rebound.cpp index 60c0d61f7..099d612ea 100644 --- a/src/objects/gachabom-rebound.cpp +++ b/src/objects/gachabom-rebound.cpp @@ -19,6 +19,7 @@ #include "../r_main.h" #include "../tables.h" #include "../s_sound.h" +#include "../k_kart.h" /* An object may not be visible on the same tic: 1) that it spawned @@ -85,7 +86,7 @@ bool award_target(mobj_t* mobj) if (rebound_timer(mobj) < 1) { player->itemtype = KITEM_GACHABOM; - player->itemamount++; + K_AdjustPlayerItemAmount(player, 1); if (player->roundconditions.gachabom_miser == 1) player->roundconditions.gachabom_miser = 0; diff --git a/src/objects/gardentop.c b/src/objects/gardentop.c index 96d64c36c..3f2a5ffd1 100644 --- a/src/objects/gardentop.c +++ b/src/objects/gardentop.c @@ -612,7 +612,7 @@ Obj_GardenTopThrow (player_t *player) } if (player->itemamount > 0) - player->itemamount--; + K_AdjustPlayerItemAmount(player, -1); if (player->itemamount <= 0) player->itemtype = KITEM_NONE; diff --git a/src/p_inter.c b/src/p_inter.c index 9619368ce..ffd05b61b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -463,9 +463,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->itemtype = special->threshold; if ((UINT16)(player->itemamount) + special->movecount > 255) - player->itemamount = 255; + K_SetPlayerItemAmount(player, 255); else - player->itemamount += special->movecount; + K_AdjustPlayerItemAmount(player, special->movecount); } } @@ -1800,16 +1800,17 @@ void P_UpdateRemovedOrbital(mobj_t *target, mobj_t *inflictor, mobj_t *source) { if (target->target->hnext && !P_MobjWasRemoved(target->target->hnext)) K_KillBananaChain(target->target->hnext, inflictor, source); - target->target->player->itemamount = 0; + + K_SetPlayerItemAmount(target->target->player, 0); } else if (target->target->player->itemamount) - target->target->player->itemamount--; + K_AdjustPlayerItemAmount(target->target->player, -1); } else if ((target->type == MT_ORBINAUT_SHIELD && target->target->player->itemtype == KITEM_ORBINAUT) // orbit items || (target->type == MT_JAWZ_SHIELD && target->target->player->itemtype == KITEM_JAWZ)) { if (target->target->player->itemamount) - target->target->player->itemamount--; + K_AdjustPlayerItemAmount(target->target->player, -1); if (target->lastlook != 0) { K_RepairOrbitChain(target); @@ -2206,15 +2207,15 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->threshold < 1 || target->threshold >= NUMKARTITEMS) // bruh moment prevention { player->itemtype = KITEM_SAD; - player->itemamount = 1; + K_SetPlayerItemAmount(player, 1); } else { player->itemtype = target->threshold; if (K_GetShieldFromItem(player->itemtype) != KSHIELD_NONE) // never give more than 1 shield - player->itemamount = 1; + K_SetPlayerItemAmount(player, 1); else - player->itemamount = max(1, target->movecount); + K_SetPlayerItemAmount(player, max(1, target->movecount)); } player->karthud[khud_itemblink] = TICRATE; player->karthud[khud_itemblinkmode] = 0; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 12e1c8f8b..e3f6824c5 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -9099,6 +9099,8 @@ void P_PostLoadLevel(void) { marathonmode = static_cast(marathonmode & ~MA_INIT); } + + Music_TuneReset(); // Placed before ACS scripts to allow remaps to occur on level start. ACS_RunLevelStartScripts(); LUA_HookInt(gamemap, HOOK(MapLoad)); diff --git a/src/y_inter.cpp b/src/y_inter.cpp index cceb14a7e..7768aec2d 100644 --- a/src/y_inter.cpp +++ b/src/y_inter.cpp @@ -295,7 +295,9 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) { UINT8 pointgetters = numplayersingame + spectateGriefed; - if (data.pos[data.numplayers] <= pointgetters) + // accept players that nocontest, but not bots + if (data.pos[data.numplayers] <= pointgetters && + !((players[i].pflags & PF_NOCONTEST) && players[i].bot)) { data.increase[i] = K_CalculateGPRankPoints((&players[i])->exp, data.pos[data.numplayers], pointgetters);