I'm a doctor, not a mechanic
Legacy:VitalOverdose/SFXHealing
Contents
Overview[edit]
In this script the mapper can set different levels of pain for pawns,vehicles and monsters.
Global Variables[edit]
TotalParticles - Internal variable not available to the mapper. TimerFrequency - Rate at which the particles are scanned. ScanSize - the radius of the scan to perform at each particle. HealthToPawn - Health to cause a pawn on contact. HealthToVec - Health to cause a vec on contact. HealthToMonster - Health to cause a Monster on contact.
Function PostBeginPlay();[edit]
In this function the .super command has been put before the modified code so we get anything from the parent class gets dealt with right away and leaves the rest of the function free for whatever code we need to add to it.
We are using the PostbeginPlay() function to check some of the data entered by the mapper before we start scanning the particle locations.
- First the MaxParticles on the active emitter is checked to see if it is higher than the Limit of 20. if it is it gets set to 20.
- The scansize Radius is checked to see it hasn't been set to low. If it is then it gets set to 64.
- Then the timerfrequency is checked to see if it lower < then 0.1 if it is, it gets set to 0.1.
- Finally the Timer is set on a continuous loop to be called every TimerFrequency seconds.
Simulated Function PostBeginPlay() { If ( Emitters[ActiveEmitterNumb].MaxParticles > 20) Destroyed(); If ( ScanSize < 1 ) ScanSize=64; If ( TimerFrequency<0.1) TimerFrequency = 0.1; SetTimer( TimerFrequency , True ); Super.PostBeginPlay(); }
Function Timer()[edit]
The timer function is rather like an alarm clock. we can set it to go off after a certain amount of time. Whats really handy about this is we can also set it to run continuously which means any code we put inside it will get called every timerfrequency seconds.
The reason for using timer() rather than tick() is to give the mapper some type of control over the amount of cpu strain that scanning the particles may cause.
- fist a local variable of type pawn is made to store the valid ref of any pawn that the iterator finds when scanning.
- A local variable of type Int is created to use as a counter in the for next loop that will cycle though the emitted particles currently being scanned.
- If a valid pawn gets found its valid actor ref is first stored in the variable FoundPawn and then passed to the function ProcessContact() along with the velocity of the particle that caused the collision x 500;
Simulated Function Timer() { local pawn foundPawn; Local Int Counter; for ( Counter=0 ; Counter < Emitters[0].Particles.Length ; Counter++ ) { foreach visiblecollidingActors(Class'pawn', foundPawn , ScanSize , Emitters[ActiveEmitterNumb].Particles[Counter].Location ) { ProcessCollision (foundPawn ,Emitters[0].Particles[Counter].Velocity*500); } } }
Function ProcessCollision()[edit]
In this function is where we do the hurting.
- A local variable of type int is created so we can calculate the amount of pain to deliver.
- The variable collidedwith which contains the valid ref of what the particle touched is checked to see if its;-
- A vec + the value stored in the variable HealthTovec is not equal to 0. If it is then thehealth is set to that value.
- If not a vec it gets checked to see if it is a monster. if it is and the variable HealthTomonster doesnt equal 0 thehealth gets set to that value.
- If not a Vehicle, it gets checked to see if it is a pawn. if it is and the variable HealthTopawn doesnt equal 0 thehealth gets set to that value.
- Function TakeHealth() is called on the pawn that the particle collided with using the details passed to this function when it was called.
Simulated Function ProcessCollision(Pawn CollidedWith, Vector ParticleMomentum) { Local Int thehealth; If ((CollidedWith.IsA('Vehicle')) && (HealthTovec!=0)) TheHealth = HealthTovec; else If ((CollidedWith.IsA('monster')) && (HealthToMonster!=0)) TheHealth = HealthTomonster; else if ((CollidedWith.IsA('Pawn')) && (HealthToPawn!=0)) TheHealth = HealthToPawn; if ( TheHealth <= 0 ) CollidedWith.Health( HealthToPawn); }
The Full Script[edit]
class SFXHealing Extends emitter placeable; var () bool bafectsMonsters; Var int TotalParticles; Var () int ActiveEmitterNumb; Var () int TimerFrequency; Var () float ScanSize; var () float HealthTovec; var () float HealthTomonster; var () float HealthTopawn; var () float healthadjustment; var () sound countactsound; var () sound rejectsound; Simulated function PostBeginPlay() { Super.PostBeginPlay(); If ( Emitters[ActiveEmitterNumb].MaxParticles > 20) //active particles capped to max20 Destroyed(); if (TimerFrequency < 0.1) TimerFrequency = 0.1; SetTimer( TimerFrequency , True ); } Simulated Function Timer() { local pawn FoundActor; Local Int Counter; for ( Counter=0 ; Counter < Emitters[0].Particles.Length ; Counter++ ) foreach visiblecollidingActors(Class'Pawn', FoundPawn , ScanSize , Emitters[ActiveEmitterNumb].Particles[Counter].Location ) if ((!foundpawn.isa('vehicle')) && (!((foundpawn.monster) && (bAfectsmonsters)))) ProcessCollision(foundpawn,emitters[0].particles[Counter].Velocity); } Simulated function ProcessCollision(pawn CollidedWith, vector Particlemomentum) { Local Int thehealth; if ((CollidedWith.IsA('Vehicle')) && (HealthTovec !=0)) TheHealth = HealthTovec; else If ((CollidedWith.IsA('monster')) && (HealthTomonster!=0)) TheHealth = HealthTomonster; else if ((CollidedWith.IsA('pawn')) && (HealthTopawn !=0)) TheHealth = HealthTopawn; if ( TheHealth <= 0 ) CollidedWith.Health( HealthToPawn); if (countactsound!=None) foundpawn.playsound(contactsound); makenoise(1); defaultproperties { bNoDelete=False RemoteRole=ROLE_SimulatedProxy }
Related Topcs[edit]
- Emitter
- Particle System
- ParticleEmitter
- ParticleEmitter Cookbook
- udn2:EmittersReference
- udn2:EmittersExamples
More custom emitter scripts[edit]
- SFXVehicleTeleporting
- SFXPainful
- SFXBoosting
- SFXTriggering
- SFXEjecting
- SFXMonsterSpawning
- SFXSelfScaling
- SFXUltraLight
- InventoryFlare
- ExampleFlares