TUTHealerAltFire - The Healer Part 6 of 9 - Complete Source Code
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)
{
FlashEmitter.Skins[0] = Texture'XEffectMat.link_muz_red';
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);
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);
}
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;
}
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;
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)
{
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;
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
{
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
LinkFlexibility=0.64
LinkBreakDelay=0.5
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
}