I love the smell of UnrealEd crashing in the morning. – tarquin
Legacy:VitalOverdose/SFXVehicleTeleporting
Contents
Overview[edit]
This custom emitter actor has 20 live particles that teleport vehicles on contact. The emitter scans the level on creation for actor with 'TP' in their tag field and record them in a dynamic array. When the vehicle is teleported it will reaper at the location of one of theses tp points (navigation points are good for this). Also it is possible to set the emitter to RE-scan the tp points at regular intervals continuously or even for a set amount of times. This means that it is possible to have moving TP points to some degree.
BotLock[edit]
There is a bot lock system build in as the vehicles receive a certain amount of boost when they exit the telporter at the tp side and this can cause the bots to panic and bail from the vehicle. With the bot lock system any vehicle that gets teleported with a bot driver will be locked so the bot cant escape for a certain amount of time (setable by the mapper in unrealed). There is also a vec 'tagging' system that can hardattach an emitter randomly chosen from a 'spawnpool' of emitters that can be set by the mapper in unreal ed.
AntiTelefrag[edit]
The teleporter will try very hard to find a safe place for the vehicle to spawn so that nothing gets telefragged. It does this by scanning the destination tp point using an iterator and if there is a possibility of a telefrage it moves on to the next random spawn point. if in the unlikely event of all the spawn spawnpoints are unsuitable then it will got through another random list but adding 128 in height each time the list gets looped.
Optimization.[edit]
Although this actor is completely self contained it has been design in a way that some of the work load by the actor doing the spawning.
Listed Features[edit]
- Scans level on creation for actors with tp in the tag field and uses them as random span points
- Tracks 20 particles from an emitter specified by the mapper or emitters[0] by default.
- Teleports all vehicles on contact with an 'active particle' to a random destination marked out by the tp points
- VecBoost on Teleport exit.
- By using the Rescan time its possible to have moving spawn Points.
- Botlock System.
- VecTagFX that can tag random emitters from a random spawnpool.
- Anti Telefrag system.
- Adjustable scan timing for level optimization.
- Adjustable scan radius on the particles.
- Possible to relive the strain on the cpu with a custom spawner.
- Rescans can be set to a certain amount;
The Script[edit]
class SFXVehicleTeleporting Extends Emitter placeable; struct Vec_Rec { Var Float Rec_Time; Var Onsvehicle Vec_Ref; };var array < Vec_Rec > Bot_Lock; Var int TotalParticles; var int RescansLeft; Var int TimeTil; var Array< Actor > TPActors; var Array< class <emitter> > TagFxPool; Var () float ScanRadius,capturetime; Var () bool Teleport_VecBot; Var () Bool Teleport_VecPlayer; Var () Sound Tagspawnsound; Var () int ActiveEmitterNo; Var () int TimerFrequency; Var () int RescanTelpoints; var () int Rescans; var () Tp_Counter TPCounter; Simulated Function PostBeginPlay() { Super.PostBeginPlay(); if (TimerFrequency < 0.1 ) // 0.1 is the min but its better to set this value a high as possible { TimerFrequency = 0.1; Warn("The timerfrequency for this actor ("$timerfrequency$") is set to LOW and has been set to the min (0.1) as a result."); Warn("If you are experiencing any problems with game speed them this may be something might want to address..."); } SetTimer( TimerFrequency , true ); if ( tpcounter != None ) return; ScanTPActors(); if ( TPActors.length == 0 ) { Warn("The initial scan for actors TP (actors with TP in their tag fields) came up with nothing."); Warn("This actor cannot function with out a TP list and had to be destroyed to avoid any other unexpected complications during game play"); destroyed(); } if ( Emitters[ActiveEmitterNo].MaxParticles > 20) { Warn("The active emitter (Emitters["$ActiveEmitterNo$"] ) has its MaxParticle rate set TO high."); destroy(); } RescansLeft = Rescans; } Simulated function ScanTPActors() { Local Actor FoundTelPoint; if ( TPActors.Length !=0 ) TPActors.Remove( 0,TPActors.Length ); foreach AllActors( Class'Actor' , FoundTelPoint, 'TP' ) { TPActors.Insert( 0,1 ); TPActors[0] = FoundTelPoint; } } Simulated Function Timer() { if ((TPCounter==None) && ( timetil > 0 )) { ProcessRescantime(); ScanPartLocs(); } if ( Bot_Lock.length > 1 ) ProcessBotLockTime(); Super.Timer(); } function EnterVec_Ref(ONSVehicle NewVec) { Bot_Lock.insert(0,1); Bot_Lock[0].Vec_Ref = NewVec; Bot_Lock[0].Rec_Time = Capturetime; } Function ScanPartLocs() { Local onsvehicle FoundOnsVec; Local Int Counter; for ( Counter = 0 ; Counter < Emitters[0].Particles.Length ; Counter++ ) // this will be run every time the Timer is called { foreach visiblecollidingActors( Class'ONSVehicle',FoundOnsVec,ScanRadius,Emitters[ActiveEmitterNo].Particles[Counter].Location ) { EnterVec_Ref(FoundOnsVec); VecTel(FoundOnsVec); } } } Function ProcessBotLockTime() { local int counter; for ( Counter = 0 ; Counter < Bot_Lock.length ; Counter++ ) // this only gets run if the vec array has soemthing in it { Bot_Lock[Counter].Rec_Time -= TimerFrequency; if ( Bot_Lock[Counter].Rec_Time < TimerFrequency ) { Bot_Lock[Counter].Vec_Ref.bDriverCannotLeaveVehicle = false; Bot_Lock.remove(Counter,1); } } } Function ProcessRescanTime() { TimeTil -= TimerFrequency; if ( TimeTil < 0 ) { ScanTPActors(); if ( RescansLeft > 0 ) { RescansLeft--; if ( RescansLeft == 0 ) TimeTil = 0; } } } Simulated function TagFx( actor SpawnPosactor, Array< Class< Emitter > > AvailableFx) { Local int RNDPickedNumb; local Class< Emitter > RNDPickedEmitter; Local Emitter SpawnedEmitter; if ( AvailableFx.Length == 0 ) Return; RNDPickedNumb = Rand(AvailableFx.Length); RNDPickedEmitter = AvailableFx[RNDPickedNumb]; while( SpawnedEmitter == none) { SpawnedEmitter = Spawn(RNDPickedEmitter,Self,,SpawnPosactor.Location ,SpawnPosactor.Rotation ); } setbase(SpawnPosactor); } Simulated Function VecTel(Vehicle Teleporting) { Local Rotator OldRot; Local Rotator Newrot; local rotator pointrotation; Local Vector AppliedBoostForce; Local Vector PointOfBoostForce; Local EPhysics Entryphysics; Local int Pickednumber; Local float HightOffSet; local vector pickedvector; NewRot = Teleporting.Rotation; EntryPhysics = Teleporting.Physics; AppliedBoostForce = Teleporting.Velocity * 500; if (tpcounter!=None) { Pickedvector = tpcounter.FindSafeSpawnLoc(HightOffSet,pointrotation); Pickedvector.z += HightOffSet; } else { Pickednumber = rand(tpactors.length-1)+1; PickedVector = tpactors[Pickednumber].location; PointRotation = tpactors[Pickednumber].Rotation; } Teleporting.SetPhysics(PHYS_None); Teleporting.SetLocation(PickedVector); OldRot = Teleporting.Rotation; NewRot.Yaw = PointRotation.Yaw + Teleporting.Rotation.Yaw - Self.Rotation.Yaw; Teleporting.SetPhysics(EntryPhysics); Teleporting.Controller.MoveTimer = -1.0; Teleporting.SetmoveTarget( Self ); Teleporting.Controller.SetRotation(newRot); Teleporting.SetRotation(newRot); If ( Teleporting.IsA('ONSChopperCraft') || Teleporting.IsA('ONSHoverCraft') || Teleporting.IsA('ONSPlaneCraft') ) Teleporting.KSetStayUpright( True,True); if (AppliedBoostForce != PointOfBoostForce) Teleporting.KAddImpulse( AppliedBoostForce >> Rotation, PointOfBoostForce >> Rotation ); if ( TagFxPool.length >0) tagfx( Teleporting , TagFxPool ); } defaultproperties { bNoDelete=False RemoteRole=ROLE_SimulatedProxy }
Related Topcs[edit]
- Vehicles
- Emitter
- Particle System
- ParticleEmitter
- ParticleEmitter Cookbook
- udn2:EmittersReference
- udn2:EmittersExamples
More custom SFX emitter scipts[edit]
- SFXPainful
- SFXBoosting
- SFXTriggering
- SFXEjecting
- SFXMonsterSpawning
- SFXHealing
- SFXSelfScaling
- SFXUltraLight
- InventoryFlare
- ExampleFlares