Worst-case scenario: the UEd Goblin wipes the map and burns down your house.

Legacy:VitalOverdose/InventoryFlare

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
UT2004 :: Actor >> Emitter >> InventoryFlare (Package: custom)

by VitalOverdose

Overview[edit]

This custom emitter actor is designed for a firework effect that can spawn an actor on detonation

This is an Abstract class and can not be place into a map. To use this actor you have to make a subclass of it and then make the flair with the subclass. Its best to have your flare made up in advance. there are some examples of properties for flare later on in this tutorial as well as some details on how to make your own.

Properties[edit]

SpawnActorclasspool         - Put in as many as you like. one will get picked at random on detonation    
Spawnoffset                 - The spawn offset range in case you want to spawn more than one actor
Spawnsound                  - Simple soundfx
SpawnAmount                 - How many actors to spawn.

First make your firework. Or you can check out a few of the ExampleFlares.

The only thing you need to remember when making a firework for this actor is that the spawning of the actor from the rocket is based on whatever the value is for Emitters(0).LifetimeRange.Max. Thats the LifetimeRange.Max in the first emitter inside your particle emitter actor (emitters[0]).

function PostBeginPlay()
 {
  SetTimer(Emitters(0).LifetimeRange.Max , False)
 }

Function Timer()[edit]

This is a very straight forward script so ive broken it down a bit to explain exactly how each bit works in detail as some of the methods used here can be used in other scripts and modifications.The two important processes are

  • The picking of a random actor from a dynamic array.
  • A for loop.
  • Randomising a vector offset when spawning.


function Timer()
{
 local Int              RNDNumb;            // Temp int variable to hole the random number picked.
 local Actor            RNDPicked_Actor;    // Temp variable type actor to hold the actor picked
                                           // based on the random number.
 local Actor            SpawnedActor;       // Variable of type actor to cause the spawn function to work
 local Vector           ActualOffset        // Temp Vector To calc the spawn pos of the actor so that
                                           // actors dont spawn on top of each other.


The Loop[edit]

Here i begin a forloop that will increment the value stored in the local variable counter starting at 0. The loop will continue untill Counter = SpawnAmount which is set by the mapper using the default properties of the subclassed Inventoryflare.

The Offset[edit]

If the is more than one object to be spawned the mapper wont want them all to spawn on the same spot setting the RangeVector called spawnoffset allows the objects limited random spawn locations.First the variable actuallofset is set to the current location of the first particle of the first emiter. Note: this is why emitters[0] cant be part of the flares trail as there would be a risk of the particle being near the end of the trail at the point of detonation. This block of code has to be the last thing to be calculated before the detonation/spawn.

 ActualOffset   = Location;
 ActualOffset.X = Rand(SpawnOffset.X.Min , SpawnOffset.x.Max);
 ActualOffset.Y = Rand(SpawnOffset.Y.Min , SpawnOffset.Y.Max);
 ActualOffset.Z = Rand(SpawnOffset.Z.Min , SpawnOffset.Z.Max);

Random Actor[edit]

Now i going to use some of the local Integer variables i defined at the start of the function. These variables are only active while this function is being run. Afterwards thay get automatically discarded. First the is a check to see if there is anything stored if the spawnactorpool before a random number is picked based on how many different actors there are in the spawnactorpool. The using this random number The local variable RNDPicked_Actor is made to equal whatever is stored in the spawnactorpool at the position[RNDNumb].

 if (SpawnActorclass.length != 0)
    {
     RNDNumb         = Rand(SpawnActorClass.Length-1)+1;
     RNDPicked_Actor = SpawnActor[RNDNumb];
    }

The Spawn[edit]

Now with the offset work out and the random actor class picked from the array its time for the spawn.

 SpawnedActor = Spawn( RNDPicked_Actor , Self ,, ActualOffset , Rotation );

Spawn OK?[edit]

As this bit of code has to be run again i cant use a 'return' function to exit if the spawn wasnt sucessfull so the next lot of code only get executed if the first argument testing the variable spawnedactor doesnt turn out to be null/none.

Once i know the spawn of the actor went ok i can take care of the rest of the cosmetic effects for the flare.before reaching the end of the forloop , incrementthe value in counter and returns to the begining.

    if ( SpawnedActor != None)
       {	
        SpawnedActor.Physics = PHYS_Falling;
 
        if ( SpawnSound != None )
           {
            PlaySound(SpawnSound,,255,,512);
           }
       }
 
     }          //<<--<<--<<-- this is the end of the for loop
} //        <<--<<-- This is the end of the function

DefaultProperties.[edit]

as this script is abstract it has to be subclassed in order for it to be placed into a level or map. Here is a list of example flares that you can use when subclassing this actor;- VitalOverdose/ExampleFlares

Full Script[edit]

Here is the completed script for this actor.

Note: this class is abstract and can not be used in a level without first making a subclass

  //=============================================================================
// InventoryFlare By vitaloverdose, Feb 2006, http://www.Vitaloverdose.com
// This is part of the 'Vitals Pro Mapping Tools' Mod
// Full class list http://wiki.beyondunreal.com/wiki/Vital's_Pro_Mapping_Tools
// Direct Download the Mod in zipped format Http://promappingtools.zapto.org
//=============================================================================
 
class InventoryFlare extends emitter
abstract;
 
Var() Array< Class<Actor> >                   SpawnActor;
var() RangeVector                             SpawnOffset;
var() Sound                                   SpawnSound;
 
function PostBeginPlay()
{
 settimer(Emitters(0).LifetimeRange.Max,false);
}
 
function Timer()
{
 local Int              RNDNumb;
 local Actor            RNDPicked_Actor;
 local Actor            SpawnedActor;
 local vector           ActualOffset;
 
 Actualoffset         = Location;
 Actualoffset.x       = Rand( SpawnOffset.X.Min , SpawnOffset.X.Max);
 Actualoffset.y       = Rand( SpawnOffset.Y.Min , SpawnOffset.Y.Max );
 Actualoffset.z       = Rand( SpawnOffset.z.Min , SpawnOffset.Z.Max );
 RNDNumb              = Rand( SpawnActor.length-1 )+1;
 RNDPicked_Actor      = SpawnActor[RNDNumb];
 While (Spawnedactor == None)
       {
        Spawnedactor = Spawn( RNDPicked_Actor , self ,, ActualOffset , Rotation );
        if ( SpawnedActor   != None )
           {
            SpawnedActor.Physics = PHYS_Falling;
            if ( Spawnsound != None )
                 PlaySound(SpawnSound,,255,,512);
          }
}
 
defaultproperties
{
bNoDelete=False
RemoteRole=ROLE_SimulatedProxy
}

InventoryFlareSpawner[edit]

An after thought really for anyone who want to use the VitalOverdose/InventoryFlare but is unsure of how to go about spawning one here is a very simple and basic InventoryFlareSpawner. It spawns a flare when triggered. It can also be set to fire a flare if shot or touched. There is a simple re-load deley that can be set as well as a sound fx.

class flarespawner extends trigger
placeable;
 
var () Array< Class< InventoryFlare > >       InventoryFlareClassPool;
var () Sound                                  SoundFX;
var () Float                                  Re_LoadDelay;
var () Bool                                   bAny_Triggers;
Var () Bool                                   bVec_Triggers;
Var () Bool                                   bPawn_Triggers;
Var () Bool                                   bMonster_Triggers;
Var () Bool                                   bProjectiles_Trigger;
var () Bool                                   bAttractsMonsters;
var    Bool                                   bReLoaded;
 
Function postbeginplay()
{
if ( Re_LoadDelay < 3 )
     Re_LoadDelay = 3;
}
 
Function Touch(actor other)
{
local emitter SpawnedE_Ref;
 
if (((other.isa('pawn')) && (bReLoaded == true)) && (InventoryFlareClassPool.length != 0))
   {
    if (((other.isa('vehicle'))    && ( bVec_Triggers))        ||
       (( other.IsA('projectile')) && ( bProjectiles_Trigger)) ||
       (( other.isa('pawn'))       && ( bPawn_Triggers ))      ||
       (( other.isa('monster'))    && ( bMonster_Triggers)))
       {
        SpawnedE_Ref = Pickflare();
        if ( SpawnedE_Ref != None)
           {
            bReloaded=false;
            if ( SoundFX != None)
               {
                playsound(SoundFX);
                if ( bAttractsMonsters )
                     makenoise(1.0);
                settimer(Re_LoadDelay,false);
               }
          }
       }
   }
}
 
function Timer()
{
 bReloaded=True;
}
 
simulated function emitter Pickflare()
{
 local emitter        SpawnedE;
 local int            pickedNumb;
 Local Class<emitter> PickedFlareClass< SEMI >
 
 pickedNumb         = rand(InventoryFlareClassPool.length-1)+1;
 PickedFlareClass   = InventoryFlareClassPool[pickedNumb];
 while (SpawnedE == none)
       {
        SpawnedE    = spawn(PickedFlareClass,self,,location,rotation);
       }
 return spawnedE;
}

Related Topcs[edit]

More custom emitter scipts[edit]

Discusion[edit]