diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 8ea013d32..0d350cedc 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -1091,6 +1091,7 @@ struct PLAYERstruct char cookieQuote[256]; // Should be an FString but must be POD for now to be storable in a savegame. int cookieTime; + char WpnReloadState; }; extern PLAYER Player[MAX_SW_PLAYERS_REG+1]; diff --git a/source/sw/src/ninja.cpp b/source/sw/src/ninja.cpp index e04755bfd..861273746 100644 --- a/source/sw/src/ninja.cpp +++ b/source/sw/src/ninja.cpp @@ -2250,6 +2250,7 @@ PlayerDeathReset(PLAYERp pp) pp->InitingNuke = FALSE; pp->NukeInitialized = FALSE; pp->BunnyMode = FALSE; + pp->WpnReloadState = 2; memset(pp->WpnAmmo,0,sizeof(pp->WpnAmmo)); memset(pp->InventoryTics,0,sizeof(pp->InventoryTics)); @@ -2339,6 +2340,7 @@ PlayerGameReset(PLAYERp pp) pp->NukeInitialized = FALSE; pp->BunnyMode = FALSE; pp->SecretsFound = 0; + pp->WpnReloadState = 2; pp->WpnAmmo[WPN_STAR] = 30; pp->WpnAmmo[WPN_SWORD] = pp->WpnAmmo[WPN_FIST] = 30; diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 123ed729c..894d95619 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -2239,6 +2239,11 @@ pUziPresent(PANEL_SPRITEp psp) psp->oy = psp->y; psp->y -= 3 * synctics; + if (psp->PlayerP->WpnUziType) + { + psp->PlayerP->WpnReloadState = 2; + } + if (psp->y < UZI_YOFF) { RESET(psp->flags, PANF_RELOAD); @@ -2261,6 +2266,8 @@ pUziPresentReload(PANEL_SPRITEp psp) psp->oy = psp->y; psp->y -= 5 * synctics; + psp->PlayerP->WpnReloadState = 2; + if (psp->y < UZI_YOFF) { psp->oy = psp->y = UZI_YOFF; @@ -2913,6 +2920,8 @@ pShotgunReloadUp(PANEL_SPRITEp psp) psp->oy = psp->y; psp->y -= 3 * synctics; + psp->PlayerP->WpnReloadState = 2; + if (psp->y < SHOTGUN_YOFF) { PlaySound(DIGI_SHOTGUN_UP, psp->PlayerP,v3df_follow|v3df_dontpan|v3df_doppler); diff --git a/source/sw/src/sbar.cpp b/source/sw/src/sbar.cpp index c4de0237e..71d2baa12 100644 --- a/source/sw/src/sbar.cpp +++ b/source/sw/src/sbar.cpp @@ -65,6 +65,22 @@ static const short icons[] = { ID_PanelCaltrops, }; +static bool DoReloadStatus(char *reloadstate, int ammo) +{ + bool reloading = ammo == 0 && *reloadstate != 2; + + if (ammo == 0 && *reloadstate == 0) + { + *reloadstate = 1; + } + if (ammo) + { + *reloadstate = 0; + } + + return reloading; +} + class DSWStatusBar : public DBaseStatusBar { DHUDFont miniFont, numberFont; @@ -801,7 +817,29 @@ private: int wicon = ammo_sprites[weapon]; if (wicon > 0) { - format.Format("%d", pp->WpnAmmo[weapon]); + int ammo = pp->WpnAmmo[weapon]; + bool reloadableWeapon = weapon == WPN_SHOTGUN || weapon == WPN_UZI; + if (!reloadableWeapon || (reloadableWeapon && !cl_showmagamt)) + { + format.Format("%d", ammo); + } + else + { + short clip; + short capacity; + switch (weapon) + { + case WPN_SHOTGUN: + capacity = 4; + clip = CalcMagazineAmount(ammo, capacity, DoReloadStatus(&pp->WpnReloadState, ammo % capacity)); + break; + case WPN_UZI: + capacity = pp->WpnUziType ? 50 : 100; + clip = CalcMagazineAmount(ammo, capacity, DoReloadStatus(&pp->WpnReloadState, ammo % capacity)); + break; + } + format.Format("%d/%d", clip, ammo - clip); + } img = tileGetTexture(wicon); imgScale = baseScale / img->GetDisplayHeight(); auto imgX = 21.125; @@ -812,7 +850,7 @@ private: imgX += (imgX * 0.855) * (strlen - 1); } - if ((!althud_flashing || gameclock & 32 || pp->WpnAmmo[weapon] > (DamageData[weapon].max_ammo / 10))) + if ((!althud_flashing || gameclock & 32 || ammo > (DamageData[weapon].max_ammo / 10))) { SBar_DrawString(this, &numberFont, format, -1.5, -numberFont.mFont->GetHeight(), DI_TEXT_ALIGN_RIGHT, CR_UNTRANSLATED, 1, 0, 0, 1, 1); }