news about forums links tools tutorials contact

Rain - author: c0mpi1e
    //=================================================
    // RainGen.
    // author: c0mpi1e(Carlos Cuello)
    // Total Time So Far: 20 hrs.
    //
    // legal: Everything in this class is 100% original and is the
    //        property of me.  It was originally
    //      produced for the USCM:Infestation TC, and any revisions
    //      to this mod will be used in that.  This is the final
    //      version that I will release to the public.  You may use
    //      this in any map and release it as part of any map you
    //      create as long as you give me full credit.  If you need
    //      anything added in particular you can email me and I'll see
    //      what I can do.
    //
    // This is basically what controls the Rain and is the only thing you
    // will have to work with.  I wanted to keep this something that anyone
    // can use, tried to keep it very configurable and tried to make
    // everything be handled from UnrealEd.  So for all you map makers,
    // simply add as many raingen's to the ceiling of the sky where you want
    // it to fall from.  The RainGen delivers a limited range of raindrops, so
    // do not expect one raingen to create a monsoon.  To change the various
    // settings for the rain, select all the RainGens in your map and click
    // on the properties dialog box, then click on the several Rain propety
    // menu's that appear(Rain_Behaviour, Rain_Looks, Rain_Sounds).  The
    // intensity variable should be kept between 0 and 5 or so to keep
    // rendering speed good.  DropSpeed should be negative for faster rain,
    // and positive for slower rain, however beware that a positive integer
    // greater than 100 or so will cause the raindrops to go up and hit the
    // ceiling.
    //
    // Note: For this release, lightning is not working, if you absolutley
    //      need it, then email me and I'll see what I can do.
    //=================================================

    class RainGen expands Effects;

    // Variables you can manipulate from UnrealED
    // This enum lets a mapper or whatnot choose between 3 different sprites
    // for the rain drop.  The parenthesis after var tells unreal that this
    // variable can be changed from Unrealed, if you put something in the
    // parenthesis then that will be the parent menu of the variable.

    var(Rain_Looks) enum ERainType
    {
      Rain_Drop,
      Rain_Line,
      Rain_LongLine
    } RainDrawType;

    var(Rain_Looks) float DropSize;    // The size of each drop
    var(Rain_Behaviour) int intensity; // The intensity of the rain
    var(Rain_Behaviour) int DropSpeed; // determines the drop speed. Neg numbers
                                       // make it drop faster, positive slows it
                                       // down, should be modified for the
                                       // default properties dialog

    var(Rain_Behaviour) int RainRadius;   // The radius of the rain, which is
                                          // random from 0 to RainRadius
    var(Rain_Behaviour) bool bThunder;
    var(Rain_Behaviour) bool bLightning;  // not implemented yet
    var(Rain_Sounds)  Sound ThunderSound1;
    var(Rain_Sounds)  Sound ThunderSound2;
    var(Rain_Sounds)  int SoundRadius;
    var(Rain_Sounds)  int RainVolume;

    // Private Variables we want to keep to ourselves

    var  int ct;      // misc counter variable, used for
                      // for loops, rather have it as a global
                      // variable because we might use it more
                      // than once.
    var  Effects D;   // the actual raindrop
    var  Effects L;   // used for lightining
    var  vector NewLoc;  // the location of the random rain drop

    // Set all our variables.
    simulated function PreBeginPlay()
    {
      Super.PreBeginPlay();

      // We want to enable the timer

      Enable('Timer');

      // Set the timer for every ten clicks we want the thunder to be
      // handled here, randomly.  If you put this into the tick function
      // it slows things down considerably.

      SetTimer(10, true);

      // Play the rain sound, using the Ambient slot

      PlaySound(EffectSound1, Slot_Ambient, RainVolume,, SoundRadius);
    }

    // Find a random number from -Max to Max
    function int RandomNeg(int Max)
    {
        local int k;
      k = Rand(Max + 1);
      if (Rand(2) == 1)
        k = -k;
      return k;

    }

    // This is where thunder and lightning are handled
    function Timer()
    {
      Super.Timer();
      if (bThunder == true && Rand(5) < 3)
      {
        // Randomly choose which thunder sound to use
        if (Frand() < 0.5)
          PlaySound(ThunderSound1, Slot_Misc, 25, true);
        else
          PlaySound(ThunderSound2, Slot_Misc, 25, true);
      }

      // If we go into the timer, but have bThunder set to false
      // then we no longer want to call the timer, we can put this before
      // in PreBeginPlay, but because we use default properties
      // to handle everything, we will not know then.
      if (bThunder == false)
        Disable('Timer');
    }

    // This is where everything takes place
    function Tick(float deltatime)
    {
      // For the number of intensity that is set from UnrealEd, then
      // spawn a new raindrop

      for (ct = 0; ct < intensity; ct ++)
        // Find a new location for the spawned RainDrop, using my
        // function RandomNeg() and base it off of the current Location
        // we only want to produce one on the horizontal plane of
        // sky or ceiling, so we leave the Z axes alone.

        NewLoc.X = Location.X + RandomNeg(RainRadius);
        NewLoc.Y = Location.Y + RandomNeg(RainRadius);
        NewLoc.Z = Location.Z;

        // Spawn a raindrop at NewLoc
        d = Spawn(class'RainDrops',,,NewLoc);

        // Set the size to what the user specified
        d.DrawScale = DropSize;

        // Same with the speeed
        d.Velocity.Z = DropSpeed;

        // Depending on what you choose for RainDrawType then set
        // the appropriate Texture.
        switch RainDrawType
        {
          case Rain_Drop:
            d.Texture = Texture'RainDrop4';
            break;
          case Rain_Line:
            d.Texture = Texture'RainLong';
            break;
          case Rain_LongLine:
            d.Texture = Texture'RainLonger';
            break;
          default:
            d.Texture = Texture'RainDrop4';

        }
      }
    }

    //============================================
    // RainDrops
    //============================================

    class RainDrops expands Effects;
    var effects d;

    function PreBeginPlay()
    {
      Super.PostBeginPlay();

      // Make the rain actually fall :)
      SetPhysics(PHYS_Falling);
    }

    // When a drop hits a wall or lands on the ground then create
    // a small rain puddle effect

    function HitWall( vector HitNormal, actor HitWall )
    {
      Super.HitWall(HitNormal, HitWall);

      // 60% chance that there will be a puddle left on the ground
      // do this to keep performance up
      if (Frand() < 0.8)
    	Spawn(class'RainPuddle',,,Location);
      Destroy();
    }

    // Same for Landed
    function Landed(vector HitNormal)
    {
      Super.Landed(HitNormal);
      if (Frand() < 0.8)
    	Spawn(class'RainPuddle',,,Location);
      Destroy();
    }

    //===========================================
    // RainPuddle.
    // Most of the code here is copied from the RingExplosion
    // code, basically I just changed the DrawScale to a smaller
    // value, I do not take any credit for this outside of that,
    // its makes a very nice effect.
    //===========================================

    class RainPuddle expands Effects;

    var bool bSpawnOnce;

    simulated function Timer()
    {
      local WaterRing r;

      if ( Level.NetMode != NM_DedicatedServer )
      {
        r = Spawn(class'WaterRing',,,,rot(16384,0,0));
        r.DrawScale = 0.02;
        r.RemoteRole = ROLE_None;
      }
      else
        Destroy();
      if (bSpawnOnce) Destroy();
      bSpawnOnce=True;
    }

    simulated function PostBeginPlay()
    {
      SetTimer(0.3,True);
    }