| Home Page | Recent Changes

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

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

FAQs

Help Desk

Mapping Topics

Mapping Lessons

UnrealEd Interface

UnrealScript Topics

UnrealScript Lessons

Making Mods

Class Tree

Modeling Topics

Chongqing Page

Log In