Announcement

Collapse
No announcement yet.

Fire/Altfire Interval Problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Fire/Altfire Interval Problem

    Through some testing it seems that base code that controls ONSWeapon, doesn't allow the AltFire weapon, to fire, until the PrimaryFire weapon has recycled.

    Is there a way to over-ride this?

    I have a tank with a regular projectile for the main gun, but I have to wait for the main gun to recycle, before I can fire the altfire machinegun.

    I haven't pasted my code, due to the fact that it's inherent from classes already existing that I am building off of. Is this changed in my vehicle class or my ONSWeapon class? What exactly do I need to add code-wise to get the functionality I need?

    thanks in advance,

    Magnum

    #2
    Not 100% sure what you mean here, but have you tried setting the

    AltFireInterval
    FireInterval

    to a low value, say like 0.01

    I looked at the ONSWeapon code, and it's using these two values to determin when the weapon can for again used in

    event bool AttemptFire(Controller C, bool bAltFire)

    I havn't tried this, but you may want to look at it.

    Comment


      #3
      For anyone interested, here's a fairly generic version of such a weapon, based (in this case) on the Raptor plasma and missiles:
      Code:
      class ONSWeaponTest extends ONSAttackCraftGun;
      
      var() bool bIndependentFire;
      
      // Internals.
      var float LastFireTime;
      var float LastAltFireTime;
      
      event bool AttemptFire(Controller C, bool bAltFire)
      {
          local float FireCountdownTemp;
          local bool bFired;
      
          if(bIndependentFire
          // Is this fire mode ready?
          && (!bAltFire
              && Level.TimeSeconds > LastFireTime + FireInterval)
          || (bAltFire
              && Level.TimeSeconds > LastAltFireTime + AltFireInterval))
          {
              // FireCountdown needs to be temporarily disabled.
              // Remember what FireCountdown was.
              FireCountdownTemp = FireCountdown;
              // Remove FireCountdown for now.
              FireCountdown = 0;
      
              // Pretend to fire as per usual.
              bFired = super.AttemptFire(C, bAltFire);
      
              if(bFired)
              {
                  // Register this shot.
                  if(!bAltFire)
                  {
                      LastFireTime = Level.TimeSeconds;
                  }
                  else
                  {
                      LastAltFireTime = Level.TimeSeconds;
                  }
      
                  // Reinstate the old FireCountdown.
                  FireCountdown = FireCountdownTemp;
              }
          }
      
          return bFired;
      }
      
      defaultproperties
      {
          bIndependentFire=true;
      }
      Both plasma and missiles can be fired independently, each using their own fire interval (the way it should have been :up: ). To use this on another weapon, simply extend the other weapon or copy/paste the code.

      @ Magnum: This is just a more generic version of what I sent you earlier.

      Comment


        #4
        Xyx,

        You are the man. I am sure this will be well recieved. I think a lot of people have wanted this functionality. I can't comprehend why ONSWeapon wasn't coded this way to begin with. Se La Vie...we as the community are like BASF...we didn't make the game, we make it better !

        Comment


          #5
          X-Man I never knew you were so smart in coding ... thanks for your assistance. :up:

          Comment


            #6
            I always hated that about the raptor, but it was a good limitation, too. It might have been unintended, but I think it makes you think twice about firing that missile.

            Comment


              #7
              BoneHead,

              I must agree with your assessment. But being a full out action FSP shooter...being without a weapon for any amount of time is a bad thing. But I also think twice before ripping off an AVRiL in a Raptor, lol! I MAKE SURE I have the shot!

              Another thing I am working on fixing now is Fire and Altfire attachements. This was so I can have my Fire from WeaponFireBone_1, and alt fire from WeaponFireBone_2. I am also adding ability to give fire and altfire their own effects: Emitter, Muzzleflash, etc. Dualfire is really messing with that part of the funtionality I want.

              Right now when I fire the Fire, it's fine, then fire Alt Fire, the first round is fired from WeaponfireBone_1, then jumps to weaponfirebone_2, and retains the Fire effects, which is unacceptable in this situtaion. My alt fire needs it's own effects.

              Is this easily fixed? I am currently copying a lot of ONSWeapon into my weapon class and rewriting support for AltFire to have it's own settings. My way will work, but may not be the easiest.

              Ok I can't seem to get anywhere, this won't compile. i am trying to get all the functionality for the weaponbone to a new weaponbone for the altfire. Here is what I have so far: (am I going about this the right way?)

              Code:
              //-----------------------------------------------------------
              //
              //-----------------------------------------------------------
              class ScorpionTankCannonB extends ONSWeapon;
              
              var float LastCannonFireTime;
              /*
              //====================================================================
              //Primary Fire
              //====================================================================
              var     vector                              WeaponFireLocation;
              var     rotator                             WeaponFireRotation;
              var()   name                                WeaponFireAttachmentBone;
              var()   float                               WeaponFireOffset;
              var     vector                              WeaponOffset;
              
              // Effects
              var()   class<Emitter>					FlashEmitterClass;
              var     Emitter							FlashEmitter;
              var()   class<Emitter>					EffectEmitterClass;
              var     Emitter							EffectEmitter;
              var()   class<ONSWeaponAmbientEmitter>  AmbientEffectEmitterClass;
              var     ONSWeaponAmbientEmitter			AmbientEffectEmitter;
              */
              //====================================================================
              //Alternate Fire
              //====================================================================
              var     rotator                             altCurrentAim;
              var     vector                              altWeaponFireLocation;
              var     rotator                             altWeaponFireRotation;
              var()   name                                altWeaponFireAttachmentBone;
              var()   float                               altWeaponFireOffset;
              var     vector                              altWeaponOffset;
              
              // Effects
              var()   class<Emitter>					altFlashEmitterClass;
              var     Emitter							altFlashEmitter;
              var()   class<Emitter>					altEffectEmitterClass;
              var     Emitter							altEffectEmitter;
              var()   class<ONSWeaponAmbientEmitter>  altAmbientEffectEmitterClass;
              var     ONSWeaponAmbientEmitter			altAmbientEffectEmitter;
              
              //var()   bool    bAmbientAltFireSound;
              
              
              var vector OldDir;
              var vector altolddir;
              var rotator OldRot;
              var rotator altoldrot;
              
              
              #exec OBJ LOAD FILE=..\Animations\ONSWeapons-A.ukx
              #exec OBJ LOAD FILE=..\Textures\BenTex01.utx
              
              //=================================================
              // Xyx's Timer goes here.  I killed dualfire.
              //=================================================
              event bool AttemptFire(Controller C, bool bAltFire)
              {
                  local float FireCountdownTemp;  
                  local bool bFired;
                
                  if(bAltFire)  
                  {  
                      // Altfire (or not) as per usual.  
                      return super.AttemptFire(C, bAltFire);  
                  }  
                  else  
                  {  
                      // Is the cannon ready?
                      if(Level.TimeSeconds > LastCannonFireTime + FireInterval)  
                      {  
                          // The cannon has its own timer and ignores FireCountdown.  For   
                          // this, FireCountdown needs to be temporarily disabled.  
                    
                          // Remember what FireCountdown was.  
                          FireCountdownTemp = FireCountdown;  
                          // Remove FireCountdown for now.  
                          FireCountdown = 0;  
                    
                          // Pretend to fire as per usual.  
                          bFired = super.AttemptFire(C, bAltFire); 
                          
                          CalcWeaponFire();    //NEW ALTFIRE STUFF
              
              
              
                          if(bFired)  
                          {
                              // Note that the cannon fired, so that it won't be fired again  
                              // until it has reloaded.  
                              LastCannonFireTime = Level.TimeSeconds;  
                              // Reinstate the old FireCountdown (for altfire).  
                              FireCountdown = FireCountdownTemp;
                          }
                
                          return bFired;  
                      }
                      else  
                      {  
                          // No go.  
                          return false;  
                      }  
                  }  
              }
              
              /*
              {
                	if(Role != ROLE_Authority || bForceCenterAim)
              		return False;
              
              	if (FireCountdown <= 0)
              	{
              		CalcWeaponFire();
              		if (bCorrectAim)
              			WeaponFireRotation = AdjustAim(bAltFire);
              		if (Spread > 0)
              			WeaponFireRotation = rotator(vector(WeaponFireRotation) + VRand()*FRand()*Spread);
              
                      	//DualFireOffset *= -1;
              
              		Instigator.MakeNoise(1.0);
              		if (bAltFire)
              		{
              			FireCountdown = AltFireInterval;
              			AltFire(C);
              		}
              		else
              		{
              		    FireCountdown = FireInterval;
              		    Fire(C);
              		}
              		AimLockReleaseTime = Level.TimeSeconds + FireCountdown * FireIntervalAimLock;
              
              	    return True;
              	}
              
              	return False;
              }
              */
              function rotator AdjustAim(bool bAltFire)
              {
              	local rotator AdjustedAim, ControllerAim;
              	local int n;
              
              	if ( (Instigator == None) || (Instigator.Controller == None) )
              		return WeaponFireRotation;
              		//return altWeaponFireRotation;     //new
              
              	if ( bAltFire )
              		n = 1;
              
              	if ( !SavedFireProperties[n].bInitialized )
              	{
              		SavedFireProperties[n].AmmoClass = class'Ammo_Dummy';
              		if ( bAltFire )
              			SavedFireProperties[n].ProjectileClass = AltFireProjectileClass;
              		else
              			SavedFireProperties[n].ProjectileClass = ProjectileClass;
              		SavedFireProperties[n].WarnTargetPct = AIInfo[n].WarnTargetPct;
              		SavedFireProperties[n].MaxRange = MaxRange();
              		SavedFireProperties[n].bTossed = AIInfo[n].bTossed;
              		SavedFireProperties[n].bTrySplash = AIInfo[n].bTrySplash;
              		SavedFireProperties[n].bLeadTarget = AIInfo[n].bLeadTarget;
              		SavedFireProperties[n].bInstantHit = AIInfo[n].bInstantHit;
              		SavedFireProperties[n].bInitialized = true;
              	}
              
              	ControllerAim = Instigator.Controller.Rotation;
              
              	AdjustedAim = Instigator.AdjustAim(SavedFireProperties[n], WeaponFireLocation, AIInfo[n].AimError);
              	//altAdjustedAim = Instigator.altAdjustAim(SavedFireProperties[n], altWeaponFireLocation, AIInfo[n].AimError);
              
              	if (AdjustedAim == Instigator.Rotation || AdjustedAim == ControllerAim)
              		return WeaponFireRotation; //No adjustment
              	else
              	{
              		AdjustedAim.Pitch = Instigator.LimitPitch(AdjustedAim.Pitch);
              		return AdjustedAim;
              }                /*
                       	else
              	{
              		altAdjustedAim.Pitch = Instigator.LimitPitch(AdjustedAim.Pitch);
              		return altAdjustedAim;
              }               */
              }
              
              //AI: return the best fire mode for the situation
              function byte BestMode()
              {
              	return Rand(2);
              }
              
              // return false if out of range, can't see target, etc.
              function bool CanAttack(Actor Other)
              {
                  local float Dist, CheckDist;
                  local vector HitLocation, HitNormal, projStart;
                  local actor HitActor;
              
                  if ( (Instigator == None) || (Instigator.Controller == None) )
                      return false;
              
                  // check that target is within range
                  Dist = VSize(Instigator.Location - Other.Location);
                  if (Dist > MaxRange())
                      return false;
              
                  // check that can see target
                  if (!Instigator.Controller.LineOfSightTo(Other))
                      return false;
              
              	if (ProjectileClass != None)
              	{
              		CheckDist = FMax(CheckDist, 0.5 * ProjectileClass.Default.Speed);
              		CheckDist = FMax(CheckDist, 300);
              		CheckDist = FMin(CheckDist, VSize(Other.Location - Location));
              	}
              	if (AltFireProjectileClass != None)
              	{
              		CheckDist = FMax(CheckDist, 0.5 * AltFireProjectileClass.Default.Speed);
              		CheckDist = FMax(CheckDist, 300);
              		CheckDist = FMin(CheckDist, VSize(Other.Location - Location));
              	}
              
                  // check that would hit target, and not a friendly
              	CalcWeaponFire();
                  projStart = WeaponFireLocation;
                  if (bInstantFire)
                      HitActor = Trace(HitLocation, HitNormal, Other.Location + Other.CollisionHeight * vect(0,0,0.8), projStart, true);
                  else
                  {
                      // for non-instant hit, only check partial path (since others may move out of the way)
                      HitActor = Trace(HitLocation, HitNormal,
                              projStart + CheckDist * Normal(Other.Location + Other.CollisionHeight * vect(0,0,0.8) - Location),
                              projStart, true);
                  }
              
                  if ( (HitActor == None) || (HitActor == Other) || (Pawn(HitActor) == None)
              		|| (Pawn(HitActor).Controller == None) || !Instigator.Controller.SameTeamAs(Pawn(HitActor).Controller) )
                      return true;
              
                  return false;
              }
              
              simulated function float MaxRange()
              {
              	if (bInstantFire)
              	{
                      if (Instigator != None && Instigator.Region.Zone != None && Instigator.Region.Zone.bDistanceFog)
              			TraceRange = FClamp(Instigator.Region.Zone.DistanceFogEnd, 8000, default.TraceRange);
              		else
              			TraceRange = default.TraceRange;
              
              		AimTraceRange = TraceRange;
              	}
              	else if ( ProjectileClass != None )
              		AimTraceRange = ProjectileClass.static.GetRange();
              	else
              		AimTraceRange = 10000;
              
              	return AimTraceRange;
              }
              
              state InstantFireMode
              {
                  function Fire(Controller C)
                  {
                      FlashMuzzleFlash();
              
                      if (AmbientEffectEmitter != None)
                      {
                          AmbientEffectEmitter.SetEmitterStatus(true);
                      }
              
                      // Play firing noise
                      if (bAmbientFireSound)
                          AmbientSound = FireSoundClass;
                      else
                          PlayOwnedSound(FireSoundClass, SLOT_None, FireSoundVolume/255.0,, FireSoundRadius, FireSoundPitch, False);
              
                      TraceFire(WeaponFireLocation, WeaponFireRotation);
                  }
              
                  function AltFire(Controller C)
                  {
                           altFlashMuzzleFlash();
              
                      if (altAmbientEffectEmitter != None)
                      {
                          altAmbientEffectEmitter.SetEmitterStatus(true);
                      }
              
                      // Play firing noise
                      if (bAmbientaltFireSound)
                          AmbientSound = altFireSoundClass;
                      else
                          PlayOwnedSound(FireSoundClass, SLOT_None, FireSoundVolume/255.0,, FireSoundRadius, FireSoundPitch, False);
              
                      TraceFire(altWeaponFireLocation, altWeaponFireRotation);
                  }
              
                  simulated event ClientSpawnHitEffects()
                  {
                  	local vector HitLocation, HitNormal, Offset;
                  	local actor HitActor;
              
                  	// if standalone, already have valid HitActor and HitNormal
                  	if ( Level.NetMode == NM_Standalone )
                  		return;
                  	Offset = 20 * Normal(altWeaponFireLocation - LastHitLocation);
                  	HitActor = Trace(HitLocation, HitNormal, LastHitLocation - Offset, LastHitLocation + Offset, False);
                  	SpawnHitEffects(HitActor, LastHitLocation, HitNormal);
                  }
              
                  simulated function SpawnHitEffects(actor HitActor, vector HitLocation, vector HitNormal)
                  {
              		local PlayerController PC;
              
              		PC = Level.GetLocalPlayerController();
              		if (PC != None && ((Instigator != None && Instigator.Controller == PC) || VSize(PC.ViewTarget.Location - HitLocation) < 5000))
              		{
              			Spawn(class'HitEffect'.static.GetHitEffect(HitActor, HitLocation, HitNormal),,, HitLocation, Rotator(HitNormal));
              			if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) )
              			{
              				// check for splash
              				if ( Base != None )
              				{
              					Base.bTraceWater = true;
              					HitActor = Base.Trace(HitLocation,HitNormal,HitLocation,Location + 200 * Normal(HitLocation - Location),true);
              					Base.bTraceWater = false;
              				}
              				else
              				{
              					bTraceWater = true;
              					HitActor = Trace(HitLocation,HitNormal,HitLocation,Location + 200 * Normal(HitLocation - Location),true);
              					bTraceWater = false;
              				}
              
              				if ( (FluidSurfaceInfo(HitActor) != None) || ((PhysicsVolume(HitActor) != None) && PhysicsVolume(HitActor).bWaterVolume) )
              					Spawn(class'BulletSplash',,,HitLocation,rot(16384,0,0));
              			}
              		}
                  }
              }
              
              state ProjectileFireMode
              {
                  function Fire(Controller C)
                  {
                  	SpawnProjectile(ProjectileClass, False);
                  	
                  	initeffects();
                  }
              
                  function AltFire(Controller C)
                  {
                      if (AltFireProjectileClass == None)
                          Fire(C);
                      else
                          SpawnProjectile(AltFireProjectileClass, True);
                  }
              }
              
              simulated event FlashMuzzleFlash()
              {
                  if (Role == ROLE_Authority)
                  {
                  	FlashCount++;
                  	NetUpdateTime = Level.TimeSeconds - 1;
                  }
                  else
                      CalcWeaponFire();
              
                  if (FlashEmitter != None)
                      FlashEmitter.Trigger(Self, Instigator);
              
                  if (altFlashEmitter != None)
                      altFlashEmitter.Trigger(Self, Instigator);
              
                  if ( (EffectEmitterClass != None) && EffectIsRelevant(Location,false) )
                      EffectEmitter = spawn(EffectEmitterClass, self,, WeaponFireLocation, WeaponFireRotation);
                      
                      if ( (altEffectEmitterClass != None) && EffectIsRelevant(Location,false) )
                      altEffectEmitter = spawn(altEffectEmitterClass, self,, altWeaponFireLocation, altWeaponFireRotation);
              }
              
              simulated event altFlashMuzzleFlash()
              {
                  if (Role == ROLE_Authority)
                  {
                  	FlashCount++;
                  	NetUpdateTime = Level.TimeSeconds - 1;
                  }
                  else
                      CalcWeaponFire();
                  /*
                  if (FlashEmitter != None)
                      FlashEmitter.Trigger(Self, Instigator);   */
              
                  if (altFlashEmitter != None)
                      altFlashEmitter.Trigger(Self, Instigator);
                   /*
                  if ( (EffectEmitterClass != None) && EffectIsRelevant(Location,false) )
                      EffectEmitter = spawn(EffectEmitterClass, self,, WeaponFireLocation, WeaponFireRotation);   */
                      
                      if ( (altEffectEmitterClass != None) && EffectIsRelevant(Location,false) )
                      altEffectEmitter = spawn(altEffectEmitterClass, self,, altWeaponFireLocation, altWeaponFireRotation);
              }
              
              simulated function DestroyEffects()
              {
                  if (FlashEmitter != None)
                      FlashEmitter.Destroy();
                  if (EffectEmitter != None)
                  	EffectEmitter.Destroy();
                  if (AmbientEffectEmitter != None)
                  	AmbientEffectEmitter.Destroy();
                  	
                  	if (altFlashEmitter != None)
                      altFlashEmitter.Destroy();
                  if (altEffectEmitter != None)
                  	altEffectEmitter.Destroy();
                  if (altAmbientEffectEmitter != None)
                  	altAmbientEffectEmitter.Destroy();
              
              }
              
              
              
              static function StaticPrecache(LevelInfo L)
              {
                  L.AddPrecacheMaterial(Material'WeaponSkins.RocketShellTex');
                  L.AddPrecacheMaterial(Material'XEffects.RocketFlare');
                  L.AddPrecacheMaterial(Material'XEffects.SmokeAlphab_t');
                  L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.TankTrail');
                  L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
                  L.AddPrecacheMaterial(Material'ONSInterface-TX.tankBarrelAligned');
                  L.AddPrecacheMaterial(Material'VMParticleTextures.TankFiringP.TankDustKick1');
                  L.AddPrecacheMaterial(Material'EmitterTextures.MultiFrame.rockchunks02');
                  L.AddPrecacheMaterial(Material'EpicParticles.Smoke.SparkCloud_01aw');
                  L.AddPrecacheMaterial(Material'BenTex01.Textures.SmokePuff01');
                  L.AddPrecacheMaterial(Material'AW-2004Explosions.Fire.Part_explode2');
                  L.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.HardSpot');
              }
              
              simulated function UpdatePrecacheMaterials()
              {
                  Level.AddPrecacheMaterial(Material'WeaponSkins.RocketShellTex');
                  Level.AddPrecacheMaterial(Material'XEffects.RocketFlare');
                  Level.AddPrecacheMaterial(Material'XEffects.SmokeAlphab_t');
                  Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.TankTrail');
                  Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.SmokePanels2');
                  Level.AddPrecacheMaterial(Material'ONSInterface-TX.tankBarrelAligned');
                  Level.AddPrecacheMaterial(Material'VMParticleTextures.TankFiringP.TankDustKick1');
                  Level.AddPrecacheMaterial(Material'EmitterTextures.MultiFrame.rockchunks02');
                  Level.AddPrecacheMaterial(Material'EpicParticles.Smoke.SparkCloud_01aw');
                  Level.AddPrecacheMaterial(Material'BenTex01.Textures.SmokePuff01');
                  Level.AddPrecacheMaterial(Material'AW-2004Explosions.Fire.Part_explode2');
                  Level.AddPrecacheMaterial(Material'AW-2004Particles.Weapons.HardSpot');
              
                  Super.UpdatePrecacheMaterials();
              }
              
              simulated function UpdatePrecacheStaticMeshes()
              {
              	Level.AddPrecacheStaticMesh(StaticMesh'WeaponStaticMesh.RocketProj');
              	Super.UpdatePrecacheStaticMeshes();
              }
              /*
              function byte BestMode()    //this is no good as we have 2 fire modes
              {
              	return 0;
              }
              */
              simulated function PostBeginPlay()
              {
              	Super.PostBeginPlay();
              
              	OldDir = Vector(CurrentAim);
              	altolddir = Vector(altcurrentaim);
              	
              	//InitEffects();
              }
              
              simulated function InitEffects()        //look here for weaponfireattach
              {
                  // don't even spawn on server
                  if (Level.NetMode == NM_DedicatedServer)
              		return;
              
                  if ( (FlashEmitterClass != None) && (FlashEmitter == None) )
                  {
                      FlashEmitter = Spawn(FlashEmitterClass);
                      FlashEmitter.SetDrawScale(DrawScale);
                      if (WeaponFireAttachmentBone == '')
                          FlashEmitter.SetBase(self);
                      else
                          AttachToBone(FlashEmitter, WeaponFireAttachmentBone);
              
                      FlashEmitter.SetRelativeLocation(WeaponFireOffset * vect(1,0,0));
                  }
                  //==============ALTFIRE
                  if ( (altFlashEmitterClass != None) && (altFlashEmitter == None) )
                  {
                      altFlashEmitter = Spawn(altFlashEmitterClass);
                      altFlashEmitter.SetDrawScale(DrawScale);
                      if (altWeaponFireAttachmentBone == '')
                          altFlashEmitter.SetBase(self);
                      else
                          AttachToBone(altFlashEmitter, altWeaponFireAttachmentBone);
              
                      altFlashEmitter.SetRelativeLocation(altWeaponFireOffset * vect(1,0,0));
                  }
                  //=======================
              
              
                  if (AmbientEffectEmitterClass != none && AmbientEffectEmitter == None)
                  {
                      AmbientEffectEmitter = spawn(AmbientEffectEmitterClass, self,, WeaponFireLocation, WeaponFireRotation);
                      if (WeaponFireAttachmentBone == '')
                          AmbientEffectEmitter.SetBase(self);
                      else
                          AttachToBone(AmbientEffectEmitter, WeaponFireAttachmentBone);
              
                      AmbientEffectEmitter.SetRelativeLocation(WeaponFireOffset * vect(1,0,0));
                  }
              }
              
              
              
              function Tick(float Delta)
              {
              	local int i;
              	local xPawn P;
              	local vector NewDir, altnewdir, PawnDir;
                  local coords WeaponBoneCoords;
                  local coords altweaponbonecoords;
              
              
                  Super.Tick(Delta);
              
              	if ( (Role == ROLE_Authority) && (Base != None) )
              	{
              	    WeaponBoneCoords = GetBoneCoords(YawBone);
              	    altweaponbonecoords = getbonecoords(yawbone);
              		NewDir = WeaponBoneCoords.XAxis ;
              		altnewdir = altweaponbonecoords.XAxis;
              
              		if ( (Vehicle(Base).Controller != None) && (NewDir.Z < 0.9) )
              		{
              			for ( i=0; i<Base.Attached.Length; i++ )
              			{
              				P = XPawn(Base.Attached[i]);
              				if ( (P != None) && (P.Physics != PHYS_None) && (P != Vehicle(Base).Driver) )
              				{
              					PawnDir = P.Location - WeaponBoneCoords.Origin;
                                                      PawnDir = P.Location - altWeaponBoneCoords.Origin;
              					PawnDir.Z = 0;
              					PawnDir = Normal(PawnDir);
              					if ( ((PawnDir.X <= NewDir.X) && (PawnDir.X > OldDir.X))
              						|| ((PawnDir.X >= NewDir.X) && (PawnDir.X < OldDir.X)) )
              					{
              						if ( ((PawnDir.Y <= NewDir.Y) && (PawnDir.Y > OldDir.Y))
              							|| ((PawnDir.Y >= NewDir.Y) && (PawnDir.X < OldDir.Y)) )
              						{
              							P.SetPhysics(PHYS_Falling);
              							P.Velocity = WeaponBoneCoords.YAxis;
              							if ( ((NewDir - OldDir) Dot WeaponBoneCoords.YAxis) < 0 )
              								P.Velocity *= -1;
              							P.Velocity = 500 * (P.Velocity + 0.3*NewDir);
              							P.Velocity.Z = 200;
              						}
              
              						if ( ((PawnDir.X <= altNewDir.X) && (PawnDir.X > altOldDir.X))
              						|| ((PawnDir.X >= altNewDir.X) && (PawnDir.X < altOldDir.X)) )
              					{
              						if ( ((PawnDir.Y <= altNewDir.Y) && (PawnDir.Y > altOldDir.Y))
              							|| ((PawnDir.Y >= altNewDir.Y) && (PawnDir.X < altOldDir.Y)) )
              						{
              							P.SetPhysics(PHYS_Falling);
              							P.Velocity = altWeaponBoneCoords.YAxis;
              							if ( ((altNewDir - altOldDir) Dot altWeaponBoneCoords.YAxis) < 0 )
              								P.Velocity *= -1;
              							P.Velocity = 500 * (P.Velocity + 0.3*NewDir);
              							P.Velocity.Z = 200;
              						}
              						}
              
              					}
              				}
              			}
              		}
              		OldDir = NewDir;
              		altolddir = altnewdir;
              	}
              }
              
              function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum);
              
              simulated function CalcWeaponFire()
              {
                  local coords WeaponBoneCoords;
                  local coords altWeaponBoneCoords;
                  local vector CurrentFireOffset;
                  local vector altfireoffset;
              
                  // Calculate fire offset in world space
                  WeaponBoneCoords = GetBoneCoords(WeaponFireAttachmentBone);  
                  altWeaponBoneCoords = GetBoneCoords(altWeaponFireAttachmentBone);
                  CurrentFireOffset = (WeaponFireOffset * vect(1,0,0)); //+ (DualFireOffset * vect(0,1,0));
                  altFireOffset = (WeaponFireOffset * vect(1,0,0));
                  // Calculate rotation of the gun
                  WeaponFireRotation = rotator(vector(CurrentAim) >> Rotation);
                  altWeaponFireRotation = rotator(vector(altCurrentAim) >> Rotation);
              
                  // Calculate exact fire location
                  WeaponFireLocation = WeaponBoneCoords.Origin + (CurrentFireOffset >> WeaponFireRotation);
                  altWeaponFireLocation = altWeaponBoneCoords.Origin + (CurrentFireOffset >> altWeaponFireRotation);
                   /*
                  // Adjust fire rotation taking dual offset into account
                  if (bDualIndependantTargeting)
                      WeaponFireRotation = rotator(CurrentHitLocation - WeaponFireLocation); */
              }
              
              defaultproperties
              {
                   YawBone="Turret"
                   PitchBone="Cannon"
                   PitchUpLimit=8000
                   PitchDownLimit=61500
                   WeaponFireAttachmentBone="WeaponFire_1"
                   altWeaponFireAttachementBone="WeaponFire_2"
                   WeaponFireOffset=200.000000
                   RotationsPerSecond=0.180000
                   Spread=0.015000
                   altspread=0.1
                   RedSkin=Shader'HaloUTScorpion_T.Vehicles.Scorpion_Shader'
                   BlueSkin=Shader'HaloUTScorpion_T.Vehicles.Scorpion_Shader'
                   FireInterval=4.000000
                   AltFireInterval=0.08
                   EffectEmitterClass=Class'HaloScorpion.ScorpionTankFireEffect'
                   FlashEmitterClass=Class'HaloScorpion.ScorpionTankMuzzleEffect'
                   altFlashEmitterClass=Class'Onslaught.ONSPRVSideGunMuzzleFlash'
                   FireSoundClass=Sound'ScorpionSounds.cannon_firing'
                   bAmbientAltFireSound=true
                   AltFireSoundClass=Sound'ONSVehicleSounds-S.PRV.PRVFire02'
                   FireSoundVolume=512.000000
                   FireForce="Explosion05"
                   ProjectileClass=Class'HaloScorpion.ScorpionRocketProjectile'
                   AltFireProjectileClass=Class'xWeapons.flakchunk'
                   ShakeRotMag=(Z=250.000000)
                   ShakeRotRate=(Z=2500.000000)
                   ShakeRotTime=6.000000
                   ShakeOffsetMag=(Z=10.000000)
                   ShakeOffsetRate=(Z=200.000000)
                   ShakeOffsetTime=10.000000
                   AIInfo(0)=(bTrySplash=True,bLeadTarget=True,WarnTargetPct=0.750000,RefireRate=0.800000)
                   Mesh=SkeletalMesh'HaloUTScorpion_A.Scorpion_T'
              }

              Comment

              Working...
              X