Game Development Community

Minor Precipitation bug

by Scott Richards · in Torque Game Engine · 10/21/2008 (5:00 pm) · 0 replies

(RE: www.garagegames.com/mg/forums/result.thread.php?qt=79257)

There is a minor bug in the Precipitation class that prevents it from clearing the drop list when you call modifyStorm(0,x) or set $pref::precipitationDensity to 0. The fault is in Precipitation::fillDropList() here:

F32 density = Con::getFloatVariable("$pref::precipitationDensity", 1.0f);
   U32 newDropCount = (U32)(mNumDrops * mPercentage * density);
   U32 dropCount = 0;
   if (mDropHead)
   {
      Raindrop* curr = mDropHead;
      while (curr)
      {
         [b]dropCount++;[/b]
         curr = curr->next;
         [b]if (dropCount == newDropCount && curr)[/b]
         {
            //delete the remaining drops
            Raindrop* next = curr->next;
            curr->next = NULL;
            while (next)
            {
               Raindrop* last = next;
               next = next->next;
               last->next = NULL;
               destroySplash(last);
               delete last;
            }
            break;
         }
      }
   }

Note how dropCount is incremented before the if () conditional? So that "if" will never get to check with a dropCount of 0; it will start at 1 and go up. Hence if newDropCount is 0, (dropCount == newDropCount) will NEVER be true, and the list won't be cleared.

To fix this, replace that whole "if (mDropHead) {...}" block with this:

if (mDropHead)
   {
      Raindrop* curr = mDropHead;
      Raindrop* last = NULL;
      while (curr)
      {
         if (dropCount == newDropCount)
         {
            //delete the remaining drops
            while (curr)
            {
               Raindrop* next = curr->next;
               destroySplash(curr);
               delete curr;
               curr = next;
            }
            // terminate list
            if (last) last->next = NULL;
            break;
         }
         last = curr;
         curr = curr->next;
         dropCount++;
      }
      if (!dropCount)
      mDropHead = NULL;
   }

and all is well.

Also, on a semi-related note, I suggest that in Precipitation::destroySplash() the line:
mSplashHead = NULL;
should be replaced with:
mSplashHead = drop->nextSplashDrop;
I have not tested that, but it doesn't seem right to me that we should break the entire list when we delete the first item. Anyone want to confirm or refute that?

---
VERSION NOTE: This all applies to v1.3 and v1.4. I suspect (can anyone confirm?) that it applies to v1.5 as well.

About the author

I am an artist, a programmer, and a rogue developer, subbornly chasing a dream, trying to make the game I want to play.