| Home Page | Recent Changes | Preferences

# TheHealer/TUTHealerAltFireSource

## TUTHealerAltFire - The Healer Part 6 of 9 - Complete Source Code

    //------------------------------------------------------------------------------
    // class name : TUTHealerAltFire
    // class type : Weapon Fire
    // description: The Healer's Secondary Fire mode
    // author     : HSDanClark
    //------------------------------------------------------------------------------
    // TODO       :
    //
    //------------------------------------------------------------------------------
    class TUTHealerAltFire extends WeaponFire;

    var TUTHealerBeamEffect Beam;
    var Sound MakeLinkSound;
    var float UpTime;
    var Pawn LockedPawn;
    var float LinkBreakTime;
    var() float LinkBreakDelay;
    var float LinkScale[6];

    var string MakeLinkForce;

    var() class<DamageType> DamageType;
    var() int Damage;
    var() float MomentumTransfer;

    var() float TraceRange;
    var() float LinkFlexibility;

    var bool bDoHit;
    var()   bool bFeedbackDeath;
    var bool bInitAimError;
    var bool bLinkFeedbackPlaying;
    var bool bStartFire;

    var rotator DesiredAimError, CurrentAimError;

    simulated function DestroyEffects()
    {
        Super.DestroyEffects();
        if ( Level.NetMode != NM_Client )
        {
            if (Beam != None)
                Beam.Destroy();
        }
    }

    simulated function ModeTick(float dt)
    {
        local Vector StartTrace, EndTrace, X,Y,Z;
        local Vector HitLocation, HitNormal, EndEffect;
        local Actor Other;
        local Rotator Aim;
        local TUTHealer TUTHealer;
        local float MT, Step;
        local bot B;
        local bool bShouldStop;
        local int AdjustedDamage;
        local TUTHealerBeamEffect LB;

        if (!bIsFiring)
        {
        bInitAimError = true;
            return;
        }
        TUTHealer = TUTHealer(Weapon);

        if (FlashEmitter != None)
        {
            // set muzzle flash color
            FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_red';

            // adjust muzzle flash size to link size
        FlashEmitter.mSizeRange[0] = FlashEmitter.default.mSizeRange[0] * 1;
        FlashEmitter.mSizeRange[1] = FlashEmitter.mSizeRange[0];
        }

        if ( TUTHealer.Ammo[ThisModeNum].AmmoAmount >= AmmoPerFire && ((UpTime > 0.0) || (Instigator.Role < ROLE_Authority)) )
        {
            UpTime -= dt;
            TUTHealer.GetViewAxes(X,Y,Z);

            // the to-hit trace always starts right in front of the eye
            StartTrace = Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius;

            TraceRange = default.TraceRange;

            if ( Instigator.Role < ROLE_Authority )
            {
            if ( Beam == None )
            foreach DynamicActors(class'TUTHealerBeamEffect', LB )
                if ( !LB.bDeleteMe && (LB.Instigator != None) && (LB.Instigator == Instigator) )
                {
                Beam = LB;
                break;
                }
                if ( Beam != None )
                LockedPawn = Beam.LinkedPawn;
        }
            if ( LockedPawn != None )
            TraceRange *= 1.5;

        if ( LockedPawn != None )
        {
            EndTrace = LockedPawn.Location + LockedPawn.EyeHeight*Vect(0,0,0.5); // beam ends at approx gun height
        }

            if ( LockedPawn == None )
            {
                if ( Bot(Instigator.Controller) != None )
                {
                if ( bInitAimError )
            {
                CurrentAimError = AdjustAim(StartTrace, AimError);
                bInitAimError = false;
            }
            else
            {
                BoundError();
                CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw;
            }
            // smooth aim error changes
            Step = 7500.0 * dt;
            if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw )
            {
                CurrentAimError.Yaw += Step;
                if ( !(DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw) )
                {
                    CurrentAimError.Yaw = DesiredAimError.Yaw;
                DesiredAimError = AdjustAim(StartTrace, AimError);
                }
            }
            else
            {
                CurrentAimError.Yaw -= Step;
                if ( DesiredAimError.Yaw ClockWiseFrom CurrentAimError.Yaw )
                {
                    CurrentAimError.Yaw = DesiredAimError.Yaw;
                DesiredAimError = AdjustAim(StartTrace, AimError);
                }
            }
            CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw;
            if ( BoundError() )
                DesiredAimError = AdjustAim(StartTrace, AimError);
                CurrentAimError.Yaw = CurrentAimError.Yaw + Instigator.Rotation.Yaw;
            Aim = Rotator(Instigator.Controller.Target.Location - StartTrace);

            Aim.Yaw = CurrentAimError.Yaw;

            // save difference
            CurrentAimError.Yaw = CurrentAimError.Yaw - Instigator.Rotation.Yaw;
                }
            else
                Aim = AdjustAim(StartTrace, AimError);

                X = Vector(Aim);
                EndTrace = StartTrace + TraceRange * X;
            }

            Other = Trace(HitLocation, HitNormal, EndTrace, StartTrace, true);
            if (Other != None && Other != Instigator)
            EndEffect = HitLocation;
            else
            EndEffect = EndTrace;
        if (Beam != None)
                Beam.EndEffect = EndEffect;

        if ( Instigator.Role < ROLE_Authority )
                return;

            if (Other != None && Other != Instigator)
            {
                // beam is updated every frame, but damage is only done based on the firing rate
                if (bDoHit)
                {
                    if (Beam != None)
                Beam.bLockedOn = false;

                        Instigator.MakeNoise(1.0);

                        AdjustedDamage = Damage;

                        if ( !Other.bWorldGeometry )
                        {
                            if (Level.Game.bTeamGame && Pawn(Other) != None && (Pawn(Other).PlayerReplicationInfo != None)
                        && Pawn(Other).PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team)
                                AdjustedDamage = 0; // so even if friendly fire is on you can't hurt teammates

                            if (Other.Physics == PHYS_Falling || Other.Physics == PHYS_Flying || Other.Physics == PHYS_Swimming)
                                MT = DeathMatch(Level.Game).LinkLockDownFactor * MomentumTransfer;
                            else
                                MT = 0.0;

                            Other.TakeDamage(AdjustedDamage, Instigator, HitLocation, MT*X, DamageType);

                            if (Beam != None)
                                Beam.bLockedOn = true;
                        }
                }

            }

            if ( bShouldStop )
            B.StopFiring();
            else
        {
            // beam effect is created and destroyed when firing starts and stops

                if ( (Beam == None) && bIsFiring )
                Beam = Spawn(class'NCHealerBeamEffect',Instigator);

            if (Beam != None)
            {
                Beam.LinkColor = 1;
            Beam.LinkedPawn = LockedPawn;
            Beam.bHitSomething = (Other != None);
            Beam.EndEffect = EndEffect;
            }
        }
        }
        else
        {
            StopFiring();
        }

        bStartFire = false;
        bDoHit = false;
    }

    function bool BoundError()
    {
        CurrentAimError.Yaw = CurrentAimError.Yaw & 65535;
        if ( CurrentAimError.Yaw > 2048 )
        {
            if ( CurrentAimError.Yaw < 32768 )
        {
            CurrentAimError.Yaw = 2048;
            return true;
        }
        else if ( CurrentAimError.Yaw < 63487 )
        {
            CurrentAimError.Yaw = 63487;
            return true;
        }
        }
        return false;
    }

    function DoFireEffect()
    {
        bDoHit = true;
        UpTime = FireRate+0.1;
    }

    function PlayFiring()
    {
        if (Weapon.Ammo[ThisModeNum].AmmoAmount >= AmmoPerFire)
        ClientPlayForceFeedback("BLinkGunBeam1");
        Super.PlayFiring();
    }

    function StopFiring()
    {
        if (Beam != None)
        {
            Beam.Destroy();
            Beam = None;
        }

        bStartFire = true;
        bFeedbackDeath = false;
        StopForceFeedback("BLinkGunBeam1");
    }

    simulated function vector GetFireStart(vector X, vector Y, vector Z)
    {
        return Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius;
    }

    defaultproperties
    {
        NoAmmoSound=Sound'WeaponSounds.P1Reload5'

        AmmoClass=class'TUTHealerAmmo'
        AmmoPerFire=1
        DamageType=class'DamTypeLinkShaft'
        Damage=10
        MomentumTransfer=20000.0
        bPawnRapidFireAnim=true

        FireAnim=AltFire
        FireEndAnim=None

        MakeLinkSound=Sound'WeaponSounds.LinkGun.LinkActivated'
        MakeLinkForce="LinkActivated"

        FlashEmitterClass=class'xEffects.LinkMuzFlashBeam1st'

        TraceRange=1100      // range of everything
        LinkFlexibility=0.64 // determines how easy it is to maintain a link.
                             // 1=must aim directly at linkee, 0=linkee can be 90 degrees to either side of you

        LinkBreakDelay=0.5   // link will stay established for this long extra when blocked (so you don't have to worry about every last tree getting in the way)

        FireRate=0.2

        BotRefireRate=0.99
        WarnTargetPct=+0.2

        ShakeOffsetMag=(X=0.0,Y=1.0,Z=1.0)
        ShakeOffsetRate=(X=1000.0,Y=1000.0,Z=1000.0)
        ShakeOffsetTime=3
        ShakeRotMag=(X=0.0,Y=0.0,Z=60.0)
        ShakeRotRate=(X=0.0,Y=0.0,Z=4000.0)
        ShakeRotTime=6

        bInitAimError=true

        LinkScale(0)=0.0
        LinkScale(1)=0.5
        LinkScale(2)=0.9
        LinkScale(3)=1.2
        LinkScale(4)=1.4
        LinkScale(5)=1.5
    }

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Image Uploads

Random Page

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

Mapping Topics

Mapping Lessons

UnrealEd Interface

Questions&Answers

Scripting Topics

Scripting Lessons

Making Mods

Class Tree

Questions&Answers

Modeling Topics

Questions&Answers

Log In