Legacy:Anozireth/IonTrigger

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to navigation Jump to search

Download IonTrigger Package

http://www.geocities.com/Anozireth/IonTrigger.html

Description

This package provides a pair of classes that allow the mapper to place a volume that will trigger the firing of an IonCannon. It allows the mapper to specify either a fixed targer or the triggering player as the target. It also allows the mapper to set the minimum time between firings and the maximum number of firings.

How to use

Simply place an IonTriggerVolume in the map where you want it, and an IonCannon that can see intended area of the target. Then configure the following settings:

bTargetPlayer 
If set to true, it will attempt to target the player which triggered it. If set to false it will target the IonTarget
IonTarget 
Optional : An Actor of the IonTriggerTarget class at the point to be targeted. Note that there are no configuration options for the IonTriggerTarget.
maxFires 
The maximum number of times this volume can trigger a firing. 0 = infinite
resetTime 
The minimum time between firings. Note that each individual cannon takes about 3 seconds to reload, so a value of less than 3 is not recommended, and may cause the cannon to not refire properly if a player is still staning in the volume when the timer resets.

Source Code

<uscript> //----------------------------------------------------------- // IonTriggerVolume - A volume that can be used to trigger an IonCannon. // By Tom Nicholson, aka Anozireth // [email protected] //----------------------------------------------------------- class IonTriggerVolume extends Volume;

var() IonTriggerTarget IonTarget; // designated target var() bool bTargetPlayer; // Targets triggering actor if true, otherwise targets IonTarget var() float resetTime; // Time between fires. This should be > 0 var() int maxFires; // Maximum number of times this volume can trigger a firing. 0 = infinite

var bool bWaitingToFire; // can we fire right now? var int firingCount; // How many times we've triggered a firing

event touch(Actor Other) { // Don't fire if not enough time has elapsed since the last firing

   if (bWaitingToFire)

return;

   // Don't fire if we're over the max number of firings
   if ( (maxFires>0) && (firingCount >= maxFires))
      return;
   if ( Pawn(Other) != none )
      	if ( Pawn(Other).IsPlayerPawn() )
           FireCannon(Pawn(Other));       // if the touch was by a player, then FIRE!

}

function IonCannon CheckMark(Pawn TargetPawn, vector MarkLocation, bool bFire) { local IonCannon I;

   // iterate through all cannons in the map until we can find one that can hit our target

foreach DynamicActors(class'IonCannon', I) { // Found a cannon, try to fire it and check if it succeeded. if ( I.CheckMark(Instigator,MarkLocation,bFire) ) {

           firingCount++;   // Keep track of how many times we've triggered a firing

return I; } }

   // didn't find a cannon that could hit the target

return None; }

function FireCannon(Pawn TargetPawn) { local vector vecTarget; // Location aimed at by cannon local vector vecNorm; // not really used, just required by trace local string s;

   // Trace straight down from the target.
   // Cannons don't seem to like shooting at points that aren't on the ground.
   if (bTargetPlayer || (IonTarget == none))  // Target the triggering player
      Trace(vecTarget,vecNorm,TargetPawn.Location+Vect(0,0,-10000), TargetPawn.Location, false);
   else    // Target the map specified target
      Trace(vecTarget,vecNorm,IonTarget.Location+Vect(0,0,-10000), IonTarget.Location, false);
   // Try to actually find a cannon and fire it
   if (CheckMark(TargetPawn,vecTarget,true) == none)
   {  // didn't fire for some reason, log error
      s = string(name) $ " Couldn't find a valid cannon to fire on Target at: " $ string(vecTarget);
      Log(s);
   }
   else
   {  // successfully fired, so reset timer
      bWaitingToFire=true;
      SetTimer(resetTime,false);
   }

}

// Checks if any pawns are touching the volume when it is re-activated function CheckIfTouching() { local actor A;

   // Don't fire if we're over the max number of firings
   if ( (maxFires>0) && (firingCount >= maxFires))
      return;

foreach TouchingActors(class'Actor', A) {

       Log("Found a touching actor");
       if ( Pawn(A) != none )
       {
           Log("Found a touching Pawn");
          	if ( Pawn(A).IsPlayerPawn() )
          	{
                Log("Found a touching PlayerPawn, firing...");
                FireCannon(Pawn(A));       // we found a player touching the volume, so FIRE!
          	     return;
          	}
       }
   }

}

// Re-Activates cannon after time delay function Timer() { bWaitingToFire=false; CheckIfTouching(); }


defaultproperties {

  maxFires=0
  resetTime=30
  bTargetPlayer=true
  bWaitingToFire=false
  bStatic=false

} </uscript>

The IonTriggerTarget class is nothing but placeable subclass of Actor -> Info and there's not really any code for it.

Discussion

Anozireth: This is my first real contribution here, so I hope you guys like it! I'm up way past my bedtime tonight so I'll have to polish this off tomorrow evening :-)

EntropicLqd: Nice. About the only change I would make to the code would be to move the checks for invalid parameters into either the PreBeingPlay() or PostBeingPlay() function. You might also want an option for an infinite amount of fires. Pretty cool though - good job well done :).

Jimbo: Indeed! I've been after a script like this for some time. Thanks for your help! (check your email, Tom)

Anozireth: EntropicLqd - I forgot to mention it in the description (at first, I added it now) but it was already in the code, 0 = infinite firings :-) I'll see if I can rework it to get those checks into one of those two functions you mentioned. Jimbo, I'll write you back on that email later today, for now I gotta get to work here. Thanks for the positive feed back guys, I'm glad you liked it!

Anozireth: I just noticed a small bug that would allow the volume to exceed its maxFires if a player was standing in it when the CheckIfTouching function was called. I've updated the code here and the download with the new package.

~~ You could simplify this by using a LookTarget instead of the custom target class.