I'm a doctor, not a mechanic

Legacy:TheHealer/TUTHealerAltFireSource

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

TUTHealerAltFire - The Healer Part 6 of 9 - Complete Source Code[edit]

//------------------------------------------------------------------------------
// 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
}