Legacy:EONSBioRifle - Unreal Wiki

# Legacy:EONSBioRifle

### From Unreal Wiki, The Unreal Engine Documentation Site

Status: Incomplete Functionality. Feel free to help me finish this weapon!

Description: The EONS Bio Rifle is intended as an improved version of the UT2004 Bio Rifle, primarily for use in the ONS gametype where long engagement ranges and the interaction of biogoo with vehicles makes the weapon subpar.

New Features:

1. Single Fire Primary is gone. Primary fire now charges up on hold. Single glob fire can be achieved via tapping the fire button.

2. (Does not work) Using the charged fire mode, the EONS Bio Rifle can be alternated between firing a single concentrated glob and a horizontal line of blobs (number of blobs determined by current charge level).

3. (Currently disabled, seeking a solution to 2.) When the aiming reticle is held on a target for a short period of time, the Bio Rifle automatically primes itself to launch glob projectiles at a higher velocity, giving the weapon additional effectiveness at longer ranges.

4. Secondary fire unleashes a stream of aerosolized bio goo, providing effective destruction in a short range at the expense of quickly expending the weapon's ammo.*

- This firing mode has a minor error that shows up in UT2004's log,

Current code is provided below.

    //===================
    // EONSBioRifle
    // Alternate Fire uses code modified from Mr. Pants' Excessive Overkill FlamethrowerEX written by Dan 'MadNad' Woodall
    //===================

    class EONSBioRifle extends BioRifle;

    var Pawn SeekTarget;
    var float LockTime, UnLockTime, SeekCheckTime;
    var bool bLockedOn, bBreakLock;
    var bool bLineSpread;
    var Sound LockOnSound, LockBrokenSound;
    var() float SeekCheckFreq, SeekRange;
    var() float LockRequiredTime, UnLockRequiredTime;
    var() float LockAim;
    var() Color CrosshairColor;
    var() float CrosshairX, CrosshairY;

    replication
    {
        reliable if (Role == ROLE_Authority && bNetOwner)
            bLockedOn;

        reliable if (Role < ROLE_Authority)
            ServerSetLineSpread, ServerClearLineSpread;
    }

    function Tick(float dt)
    {
        local Pawn Other;
        local Vector StartTrace;
        local Rotator Aim;
        local float BestDist, BestAim;

        if (Instigator == None || Instigator.Weapon != self)
            return;

        if ( Role < ROLE_Authority )
            return;

        if ( !Instigator.IsHumanControlled() )
            return;

        if (Level.TimeSeconds > SeekCheckTime)
        {
            if (bBreakLock)
            {
                bBreakLock = false;
                bLockedOn = false;
                SeekTarget = None;
            }

            StartTrace = Instigator.Location + Instigator.EyePosition();
            Aim = Instigator.GetViewRotation();

            BestAim = LockAim;
            Other = Instigator.Controller.PickTarget(BestAim, BestDist, Vector(Aim), StartTrace, SeekRange);

            if ( CanLockOnTo(Other) )
            {
                if (Other == SeekTarget)
                {
                    LockTime += SeekCheckFreq;
                    if (!bLockedOn && LockTime >= LockRequiredTime)
                    {
                        bLockedOn = true;
                        PlayerController(Instigator.Controller).ClientPlaySound(LockOnSound);
                     }
                }
                else
                {
                    SeekTarget = Other;
                    LockTime = 0.0;
                }
                UnLockTime = 0.0;
            }
            else
            {
                if (SeekTarget != None)
                {
                    UnLockTime += SeekCheckFreq;
                    if (UnLockTime >= UnLockRequiredTime)
                    {
                        SeekTarget = None;
                        if (bLockedOn)
                        {
                            bLockedOn = false;
                            PlayerController(Instigator.Controller).ClientPlaySound(LockBrokenSound);
                        }
                    }
                }
                else
                     bLockedOn = false;
             }

            SeekCheckTime = Level.TimeSeconds + SeekCheckFreq;
        }
    }

    function bool CanLockOnTo(Actor Other)
    {
        local Pawn P;

        P = Pawn(Other);

        if (P == None || P == Instigator || !P.bProjTarget)
            return false;

        if (!Level.Game.bTeamGame)
            return true;

        if ( (Instigator.Controller != None) && Instigator.Controller.SameTeamAs(P.Controller) )
            return false;

        return ( (P.PlayerReplicationInfo == None) || (P.PlayerReplicationInfo.Team != Instigator.PlayerReplicationInfo.Team) );
    }

    simulated event RenderOverlays( Canvas Canvas )
    {
        if (bLockedOn)
        {
            Canvas.DrawColor = CrosshairColor;
            Canvas.DrawColor.A = 255;
            Canvas.Style = ERenderStyle.STY_Alpha;

            Canvas.SetPos(Canvas.SizeX*0.5-CrosshairX, Canvas.SizeY*0.5-CrosshairY);
            Canvas.DrawTile(Texture'SniperArrows', CrosshairX*2.0, CrosshairY*2.0, 0.0, 0.0, Texture'SniperArrows'.USize, Texture'SniperArrows'.VSize);
        }

        Super.RenderOverlays(Canvas);
    }

    simulated function SetLineSpread(bool bNew, optional bool bForce)
    {
        if ( (bLineSpread != bNew) || bForce )
        {
            bLineSpread = bNew;
            if ( bLineSpread )
                ServerSetLineSpread();
            else
                ServerClearLineSpread();
        }
    }

    function ServerClearLineSpread()
    {
        bLineSpread = false;
    }

    function ServerSetLineSpread()
    {
        bLineSpread = true;
    }

    //

    //This determines Volley/Spread
    simulated event ClientStartFire(int Mode)
    {
        local int OtherMode;

        if ( EONSBioMultiFire(FireMode[Mode]) != None )
        {
            SetLineSpread(false);
        }
        else
        {
            if ( Mode == 0 )
                OtherMode = 1;
            else
                OtherMode = 0;

            if ( FireMode[OtherMode].bIsFiring || (FireMode[OtherMode].NextFireTime > Level.TimeSeconds) )
            {
                //if ( FireMode[OtherMode].Load > 0 )
                    SetLineSpread(true);
                if ( bDebugging )
                    log("No RL reg fire because other firing "$FireMode[OtherMode].bIsFiring$" next fire "$(FireMode[OtherMode].NextFireTime - Level.TimeSeconds));
                return;
            }
        }
        Super.ClientStartFire(Mode);
    }

    simulated function bool StartFire(int Mode)
    {
        local int OtherMode;

        if ( Mode == 0 )
            OtherMode = 1;
        else
            OtherMode = 0;
        if ( FireMode[OtherMode].bIsFiring || (FireMode[OtherMode].NextFireTime > Level.TimeSeconds) )
            return false;

        return Super.StartFire(Mode);
    }

    //

    defaultproperties
    {
        ItemName="EONS Bio-Rifle"

        FireModeClass(0)=EONSBioMultiFire
        FireModeClass(1)=EONSBioAltFire
        InventoryGroup=3

        PickupClass=class'EONSBioRiflePickup'
        EffectOffset=(X=100.0,Y=32.0,Z=-20.0)
        AttachmentClass=class'BioAttachment'
        PutDownAnim=PutDown

        DisplayFOV=60
        DrawScale=1.0
        PlayerViewOffset=(X=7,Y=3,Z=0)
        SmallViewOffset=(X=19,Y=9,Z=-6)

        PlayerViewPivot=(Pitch=0,Roll=0,Yaw=0)
        SelectSound=Sound'WeaponSounds.FlakCannon.SwitchToFlakCannon'
        SelectForce="SwitchToFlakCannon"

        AIRating=+0.55
        CurrentRating=+0.55

        SeekCheckFreq=0.2
        SeekRange=10240
        LockRequiredTime=0.4
        UnLockRequiredTime=0.6
        LockAim=0.996 // 5 deg

        CustomCrosshairColor=(r=0,g=255,b=0,a=255)

        //Lock On Attr
        CrosshairColor=(R=0,G=255,B=0,A=255)
        CrosshairX=32
        CrosshairY=32
        LockOnSound=Sound'WeaponSounds.TAGRifle.TagTargetAquired'
        LockBrokenSound=Sound'WeaponSounds.TAGRifle.TagTargetAquired'

        CenteredOffsetY=-8.0
    }

    //===================
    // EONSBioMultiFire
    //===================

    class EONSBioMultiFire extends BioChargedFire;

    var() float TightSpread, LineSpread;

    event ModeDoFire()
    {
        if ( EONSBioRifle(Weapon).bLineSpread || ((Bot(Instigator.Controller) != None) && (FRand() < 0.65)) )
        {
            Spread = LineSpread;
            SpreadStyle = SS_Line;
        }
        else
        {
            SpreadStyle = SS_Ring;
            Spread = TightSpread;
        }
        EONSBioRifle(Weapon).bLineSpread = false;
        Super(ProjectileFire).ModeDoFire();
        NextFireTime = FMax(NextFireTime, Level.TimeSeconds + FireRate);
    }

    /*
    function DoFireEffect()
    {
     Load = GoopLoad;
     Super.DoFireEffect();
    }
    */

    function DoFireEffect()
    {
        local EONSBioGlob FiredGlobs[10];
        local Vector StartProj, StartTrace, X,Y,Z;
        local Rotator Aim;
        local Vector HitLocation, HitNormal,FireLocation;
        local int p;
        local Actor Other;
        local float theta;

        if (SpreadStyle != SS_Line)
        {
            Log("DoFireEffect: SpreadStyle != Line");
            Super.DoFireEffect();
            return;
        }

        Instigator.MakeNoise(1.0);
        Weapon.GetViewAxes(X,Y,Z);

        StartTrace = Instigator.Location + Instigator.EyePosition();
        StartProj = StartTrace + X*ProjSpawnOffset.X + Z*ProjSpawnOffset.Z;
        if ( !Weapon.WeaponCentered() )
            StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y;

        // check if projectile would spawn through a wall and adjust start location accordingly
        Other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false);
        if (Other != None)
        {
            StartProj = HitLocation;
        }

        Aim = AdjustAim(StartProj, AimError);

        Log("DoFireEffect: SpreadStyle == Line");
        for (p = 0; p < GoopLoad; p++)
            {
                theta = Spread*PI/32768*(p - float(GoopLoad-1)/2.0);
                X.X = Cos(theta);
                X.Y = Sin(theta);
                X.Z = 0.0;
                //SpawnProjectile(StartProj, Rotator(X >> Aim));
                FiredGlobs[p] = EONSBioGlob(SpawnProjectile(FireLocation, Rotator(X >> Aim)));
            }

    }

    function projectile SpawnProjectile(Vector Start, Rotator Dir)
    {
        local EONSBioGlob Glob;

        GotoState('');

        if (GoopLoad == 0) return None;

        if (Spread != LineSpread) //(!EONSBioRifle(Weapon).bLineSpread)
        {
           Glob = Weapon.Spawn(class'EONSBioGlob',,, Start, Dir);
           Log("Check 1");
           if ( Glob != None )
           {
              Glob.Damage *= DamageAtten;
              Glob.SetGoopLevel(GoopLoad);
              Glob.AdjustSpeed();
           }
        }
        else
        {

           Log("Check 2");
           if ( Glob != None )
           {
              Glob.Damage *= DamageAtten;
              Glob.SetGoopLevel(1);
              Glob.AdjustSpeed();
           }
        }
        GoopLoad = 0;
        if ( Weapon.AmmoAmount(ThisModeNum) <= 0 )
            Weapon.OutOfAmmo();
        return Glob;
    }

    defaultproperties
    {
        AmmoClass=class'EONSBioAmmo'
        AmmoPerFire=1

        FireAnim=AltFire
        FireAnimRate=1.0

        ProjectileClass=class'EONSBioGlob'

        FlashEmitterClass=class'XEffects.BioMuzFlash1st'

        SpreadStyle=SS_Line
        TightSpread=300
        LineSpread=500

        ProjSpawnOffset=(X=25,Y=6,Z=-6)

        FireSound=Sound'WeaponSounds.BioRifle.BioRifleFire'

        FireForce="RocketLauncherFire"  // jdf

        FireRate=0.33
        TweenTime=0.0

        bFireOnRelease=true
        //MaxHoldTime=10.5 // FireRate*2 + 0.5

        bSplashDamage=true
        bRecommendSplashDamage=true
        BotRefireRate=0.6
        WarnTargetPct=+0.9
        bSplashJump=true

        ShakeOffsetMag=(X=-20.0,Y=0.00,Z=0.00)
        ShakeOffsetRate=(X=-1000.0,Y=0.0,Z=0.0)
        ShakeOffsetTime=2
        ShakeRotMag=(X=0.0,Y=0.0,Z=0.0)
        ShakeRotRate=(X=0.0,Y=0.0,Z=0.0)
        ShakeRotTime=2
    }

    //=========================================================================
    // EONSBioAltFire
    // Alternate Fire uses code modified from Mr. Pants' Excessive Overkill FlamethrowerEX written by Dan 'MadNad' Woodall
    // ========================================================================

    class EONSBioAltFire extends ProjectileFire;

    var xEmitter BGas;

    function Projectile SpawnProjectile(Vector Start, Rotator Dir)
    {
        local Projectile P;

        if ( class'PlayerController'.Default.bSmallWeapons || Level.bClassicView )
           ProjSpawnOffset.Z = -20;

        else
           ProjSpawnOffset.Z = default.ProjSpawnOffset.Z;

        if( ProjectileClass != None )
            P = Spawn(ProjectileClass,,, Start, Dir);

        if( P == None )
            return None;

        P.Damage *= DamageAtten;

        return P;

    }

    event ModeDoFire()
    {
            local Vector Dir;

            super.ModeDoFire();

            Dir = Vector(Weapon.Rotation);

            if ( Weapon.AmmoAmount(0) > 1 && !Instigator.isA('Bot') )
                EONSBioRifle(Weapon).SoundVolume=255;

            BGas=spawn(class'EONSBioGasIgnite',Owner,,,);
            Weapon.AttachToBone(BGas, 'tip');
      BGas.mSpeedRange[0]+=Abs(VSize(Instigator.Velocity/VSize(Dir)));
      BGas.mSpeedRange[1]+=Abs(VSize(Instigator.Velocity/VSize(Dir)));
            if ( Weapon.ammoAmount(0) < 2 )
                EONSBioRifle(Weapon).SoundVolume=0;
    }

    simulated function StopFiring()
    {
                    EONSBioRifle(Weapon).SoundVolume=0;
    }

    defaultproperties
    {
         ProjSpawnOffset=(Y=40.000000)
         bPawnRapidFireAnim=True
         FireForce="minifireb"
         FireRate=0.06
         AmmoClass=Class'EONSBioAmmo'
         AmmoPerFire=1
         ShakeRotMag=(X=15.000000,Y=15.000000,Z=15.000000)
         ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
         ShakeRotTime=2.000000
         ShakeOffsetMag=(X=-5.000000)
         ShakeOffsetRate=(X=-500.000000)
         ShakeOffsetTime=2.000000
         ProjectileClass=Class'EONSBioGasProj'
         BotRefireRate=0.990000
         aimerror=120.000000
         Spread=2000.000000
    }

##### Views

- Legacy
- Discussion
- Current revision

##### Search