| Home Page | Recent Changes | Preferences

TheHealer/TUTHealerFireSource

TUTHealerFire - The Healer Part 5 of 9 - Complete Source Code

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

const NoDamage = 0;

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 TUTHealerBeamEffect LB;
    local Pawn P;

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


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

        // 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);

                if ( !Other.bWorldGeometry )
                {
                    P = Pawn(Other);

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

                    // This is the key, this is where we give health instead of taking damage.
                    P.GiveHealth(3,199);
  
                    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'TUTHealerBeamEffect',Instigator);

    if (Beam != None)
    {
            Beam.LinkColor = 0;
            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;
}

function StartBerserk()
{
//    Damage = default.Damage * 1.33;
//    Damage = default.Damage * 1.33;
}

function StopBerserk()
{
//    Damage = default.Damage;
//    Damage = default.Damage;
}

defaultproperties
{
    NoAmmoSound=Sound'WeaponSounds.P1Reload5'

    AmmoClass=class'TUTHealerAmmo'
    AmmoPerFire=1
    DamageType=class'DamTypeLinkShaft'
    Damage=-15
    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