diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5eefc9c7e..3d7fbbd50 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4359,8 +4359,8 @@ static void HWR_AddPrecipitationSprites(void) fixed_t drawdist; - // save a little time on invisible weather - if (curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) + // save a little time if theres no or invisible weather + if (curWeather == PRECIP_NONE || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) { return; } diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 14980b162..e54d1df06 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -577,8 +577,7 @@ static void PS_CountThinkers(void) ps_removecount.value.i = 0; for (thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next) { - if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker) - ps_thinkercount.value.i++; + ps_thinkercount.value.i++; if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) ps_removecount.value.i++; @@ -593,11 +592,18 @@ static void PS_CountThinkers(void) else ps_regularcount.value.i++; } - else if (thinker->function.acp1 == (actionf_p1)P_NullPrecipThinker) - ps_precipcount.value.i++; else ps_otherthcount.value.i++; } + + for (thinker = precipcap.next; thinker != &precipcap; thinker = thinker->next) + { + if (thinker->function.acp1 != (actionf_p1)P_NullPrecipThinker) + continue; // not a precipmobj thinker + + ps_precipcount.value.i++; + } + /*for (i = 0; i < NUM_THINKERLISTS; i++) { for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) diff --git a/src/p_local.h b/src/p_local.h index ea0bff603..acb62ad67 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -66,10 +66,12 @@ // both the head and tail of the thinker list extern thinker_t thinkercap; +extern thinker_t precipcap; extern mobj_t *mobjcache; void P_InitThinkers(void); void P_AddThinker(thinker_t *thinker); +void P_AddPrecipThinker(thinker_t *thinker); void P_RemoveThinker(thinker_t *thinker); void P_UnlinkThinker(thinker_t *thinker); diff --git a/src/p_mobj.c b/src/p_mobj.c index 03e7e9f99..c9a316087 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10003,7 +10003,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->momz = cv_mobjscaleprecip.value ? FixedMul(info->speed, mapobjectscale) : info->speed; mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker; - P_AddThinker(&mobj->thinker); + P_AddPrecipThinker(&mobj->thinker); CalculatePrecipFloor(mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index 898a53d68..7bdea61b4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1680,8 +1680,7 @@ static void P_NetArchiveThinkers(savebuffer_t *save) // save off the current thinkers for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed - || th->function.acp1 == (actionf_p1)P_NullPrecipThinker)) + if (th->function.acp1 != (actionf_p1)P_RemoveThinkerDelayed) numsaved++; if (th->function.acp1 == (actionf_p1)P_MobjThinker) @@ -1689,9 +1688,6 @@ static void P_NetArchiveThinkers(savebuffer_t *save) SaveMobjThinker(save, th, tc_mobj); continue; } -#ifdef PARANOIA - else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker); -#endif else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) { SaveCeilingThinker(save, th, tc_ceiling); @@ -2671,6 +2667,8 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) { thinker_t *currentthinker; thinker_t *next; + thinker_t *currentprecipthinker; + thinker_t *nextprecip; UINT8 tclass; UINT8 restoreNum = false; UINT32 i; @@ -2685,7 +2683,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) { next = currentthinker->next; - if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker || currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker) + if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) P_RemoveSavegameMobj((mobj_t *)currentthinker); // item isn't saved, don't remove it else { @@ -2695,6 +2693,24 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) } } + // remove all the current precip thinkers + currentprecipthinker = precipcap.next; + for (currentprecipthinker = precipcap.next; currentprecipthinker != &precipcap; currentprecipthinker = nextprecip) + { + nextprecip = currentprecipthinker->next; + +#ifdef PARANOIA + if (currentprecipthinker->function.acp1 != (actionf_p1)P_NullPrecipThinker) + { + (next->prev = currentprecipthinker->prev)->next = nextprecip; + R_DestroyLevelInterpolators(currentprecipthinker); + Z_Free(currentprecipthinker); + } + else +#endif + P_RemoveSavegameMobj((mobj_t *)currentprecipthinker); // item isn't saved, don't remove it + } + // we don't want the removed mobjs to come back iquetail = iquehead = 0; P_InitThinkers(); diff --git a/src/p_spec.c b/src/p_spec.c index d272764be..fc25a94ad 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1779,12 +1779,14 @@ void P_SwitchWeather(INT32 weathernum) thinker_t *next; precipmobj_t *precipmobj; - for (think = thinkercap.next; think != &thinkercap; think = next) + for (think = precipcap.next; think != &precipcap; think = next) { next = think->next; +#ifdef PARANOIA if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker +#endif precipmobj = (precipmobj_t *)think; P_FreePrecipMobj(precipmobj); @@ -1796,10 +1798,12 @@ void P_SwitchWeather(INT32 weathernum) precipmobj_t *precipmobj; state_t *st; - for (think = thinkercap.next; think != &thinkercap; think = think->next) + for (think = precipcap.next; think != &precipcap; think = think->next) { +#ifdef PARANOIA if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker +#endif precipmobj = (precipmobj_t *)think; diff --git a/src/p_tick.c b/src/p_tick.c index 3b0cadde8..aec4aba20 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -49,6 +49,7 @@ tic_t leveltime; // Both the head and tail of the thinker list. thinker_t thinkercap; +thinker_t precipcap; void Command_Numthinkers_f(void) { @@ -56,6 +57,7 @@ void Command_Numthinkers_f(void) INT32 count = 0; actionf_p1 action; thinker_t *think; + thinker_t *listtype; if (gamestate != GS_LEVEL) { @@ -104,7 +106,9 @@ void Command_Numthinkers_f(void) return; } - for (think = thinkercap.next; think != &thinkercap; think = think->next) + listtype = (num == 2) ? &precipcap : &thinkercap; + + for (think = listtype->next; think != listtype; think = think->next) { if (think->function.acp1 != action) continue; @@ -181,6 +185,7 @@ void Command_CountMobjs_f(void) void P_InitThinkers(void) { thinkercap.prev = thinkercap.next = &thinkercap; + precipcap.prev = precipcap.next = &precipcap; waypointcap = NULL; } @@ -200,6 +205,22 @@ void P_AddThinker(thinker_t *thinker) thinker->cachable = (thinker->function.acp1 == (actionf_p1)P_MobjThinker); } +// +// P_AddPrecipThinker +// Adds a new precip thinker at the end of the list. +// +void P_AddPrecipThinker(thinker_t *thinker) +{ + precipcap.prev->next = thinker; + thinker->next = &precipcap; + thinker->prev = precipcap.prev; + precipcap.prev = thinker; + + thinker->references = 0; // killough 11/98: init reference counter to 0 + + thinker->cachable = false; +} + // // killough 11/98: // @@ -341,8 +362,6 @@ static inline void P_RunThinkers(void) { for (currentthinker = thinkercap.next; currentthinker != &thinkercap; currentthinker = currentthinker->next) { - if (currentthinker->function.acp1 == (actionf_p1)P_NullPrecipThinker) - continue; #ifdef PARANOIA I_Assert(currentthinker->function.acp1 != NULL) #endif diff --git a/src/r_main.c b/src/r_main.c index 9541fef41..51c590d46 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -284,12 +284,14 @@ static void Precipstuff_OnChange(void) thinker_t *next; precipmobj_t *precipmobj; - for (think = thinkercap.next; think != &thinkercap; think = next) + for (think = precipcap.next; think != &precipcap; think = next) { next = think->next; +#ifdef PARANOIA if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker +#endif precipmobj = (precipmobj_t *)think; P_FreePrecipMobj(precipmobj); diff --git a/src/r_things.c b/src/r_things.c index 94d108fec..f4638c5b1 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1969,14 +1969,20 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) // void R_AddPrecipitationSprites(void) { - fixed_t precipscale = (cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT); - fixed_t drawdist = ((fixed_t)(cv_drawdist_precip.value) * precipscale); - INT32 xl, xh, yl, yh, bx, by; precipmobj_t *th, *next; + // save a little time if theres no or invisible weather + if (curWeather == PRECIP_NONE || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) + { + return; + } + + const fixed_t precipscale = (cv_mobjscaleprecip.value ? mapobjectscale : FRACUNIT); + const fixed_t drawdist = ((fixed_t)(cv_drawdist_precip.value) * precipscale); + // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off - if (drawdist == 0 || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) + if (drawdist == 0) { return; }