class NiceZombieTeslaHusk extends NiceZombieHusk; #exec OBJ LOAD FILE=KF_EnemiesFinalSnd_CIRCUS.uax #exec OBJ LOAD FILE=ScrnZedPack_A.ukx #exec OBJ LOAD FILE=ScrnZedPack_T.utx #exec OBJ LOAD FILE=ScrnZedPack_SM.usx var class BeamClass; var TeslaBeam PrimaryBeam; var float MaxPrimaryBeamRange; // how far Husk can shoot with his tesla gun? var float MaxChildBeamRange; // max distance from primary target for a chain reaction var float ChainedBeamRangeExtension; // if pawn is already chained, chain max range is multiplied by this value // used for optimization var private float MaxPrimaryBeamRangeSquared, MaxChildBeamRangeSquared; var float Energy; var float EnergyMax; var float EnergyRestoreRate; var() float DischargeDamage; // beam damage per second var() float ChainDamageMult; // how much damage drops on the next chain var() class MyDamageType; var() byte MaxChainLevel; var() int MaxChainActors; var ZedBeamSparks DecapitationSparks; var bool bChainThoughZED; // chain tesla beam though a zed, which is between target and the husk, to extend firing range var transient float NextChainZedSearchTime; var transient float ChainRebuildTimer; // how many seconds between rebuilding chained actors var float DischargeRate; // time between damaging chained pawns. Do not set it too low due to rounding precission of DischargeDamage var transient float LastDischargeTime; // Tesla Husks are able to heal each other. var() float HealRate; // Percent of HealthMax to heal per second var() float HealEnergyDrain; // amount of energy required to heal 1% var transient float NextHealAttemptTime, LastHealTime; struct SActorDamages { var Actor Victim; var int Damage; }; var protected array DischargedActors; simulated function PostBeginPlay() { // Difficulty Scaling if(Level.Game != none && !bDiffAdjusted) { if(Level.Game.GameDifficulty >= 5.0){ DischargeDamage *= 1.75; EnergyMax *= 1.75; EnergyRestoreRate *= 1.75; MaxPrimaryBeamRange *= 1.75; MaxChildBeamRange *= 1.75; } else{ DischargeDamage *= 1.0; EnergyMax *= 1.0; EnergyRestoreRate *= 1.0; MaxPrimaryBeamRange *= 1.0; MaxChildBeamRange *= 1.0; } } Energy = EnergyMax; MaxPrimaryBeamRangeSquared = MaxPrimaryBeamRange * MaxPrimaryBeamRange; MaxChildBeamRangeSquared = MaxChildBeamRange * MaxChildBeamRange; NextHealAttemptTime = Level.TimeSeconds + 5.0; super.PostBeginPlay(); BurnDamageScale = 1.0; // no fire damage resistance } simulated function HideBone(name boneName) { local int BoneScaleSlot; local bool bValidBoneToHide; if( boneName == LeftThighBone ) { boneScaleSlot = 0; bValidBoneToHide = true; } else if ( boneName == RightThighBone ) { boneScaleSlot = 1; bValidBoneToHide = true; } else if( boneName == RightFArmBone ) { boneScaleSlot = 2; bValidBoneToHide = true; } else if ( boneName == LeftFArmBone ) { boneScaleSlot = 3; bValidBoneToHide = true; } else if ( boneName == HeadBone ) { // Only scale the bone down once if( SeveredHead == none ) { bValidBoneToHide = true; boneScaleSlot = 4; } else { return; } } else if ( boneName == 'spine' ) { bValidBoneToHide = true; boneScaleSlot = 5; } // Only hide the bone if it is one of the arms, legs, or head, don't hide other misc bones if( bValidBoneToHide ) { SetBoneScale(BoneScaleSlot, 0.0, BoneName); } } function TeslaBeam SpawnTeslaBeam() { local TeslaBeam beam; beam = spawn(BeamClass, self); if ( beam != none ) { beam.Instigator = self; } return beam; } function TeslaBeam SpawnPrimaryBeam() { if ( PrimaryBeam == none ) { PrimaryBeam = SpawnTeslaBeam(); PrimaryBeam.StartActor = self; PrimaryBeam.StartBoneName = 'Barrel'; } return PrimaryBeam; } function FreePrimaryBeam() { if ( PrimaryBeam != none ) { //PrimaryBeam.DestroyChildBeams(); PrimaryBeam.EndActor = none; PrimaryBeam.EffectEndTime = Level.TimeSeconds - 1; PrimaryBeam.Instigator = none; // mark to delete PrimaryBeam = none; } } function RangedAttack(Actor A) { local float Dist; local NiceMonster M; if ( bShotAnim || bDecapitated ) return; Dist = VSize(A.Location - Location); if ( Physics == PHYS_Swimming ) { SetAnimAction('Claw'); bShotAnim = true; } else if ( Energy < 100 && Dist < MeleeRange + CollisionRadius + A.CollisionRadius ) // do melee hits only when low on energy { bShotAnim = true; SetAnimAction('Claw'); //PlaySound(sound'Claw2s', SLOT_Interact); KFTODO: Replace this Controller.bPreparingMove = true; Acceleration = vect(0,0,0); } else if ( Energy > 50 && Dist < MaxPrimaryBeamRange*(0.7 + 0.3*frand()) ) { bShotAnim = true; SetAnimAction('ShootBurns'); Controller.bPreparingMove = true; Acceleration = vect(0,0,0); NextFireProjectileTime = Level.TimeSeconds + ProjectileFireInterval + (FRand() * 2.0); } else if ( bChainThoughZED && Energy > 100 && Controller.Enemy == A && KFPawn(A) != none && NextChainZedSearchTime < Level.TimeSeconds && Dist < MaxPrimaryBeamRange + MaxChildBeamRange ) { NextChainZedSearchTime = Level.TimeSeconds + 3.0; foreach VisibleCollidingActors(class'NiceMonster', M, MaxPrimaryBeamRange*0.9) { if ( !M.bDeleteMe && M.Health > 0 && NiceZombieTeslaHusk(M) == none && VSizeSquared(M.Location - A.Location) < MaxChildBeamRangeSquared*0.9 && M.FastTrace(A.Location, M.Location) ) { Controller.Target = M; RangedAttack(M); return; } } } } function SpawnTwoShots() { SpawnPrimaryBeam(); if ( PrimaryBeam == none ) { log("Unable to spawn Primary Beam!", 'TeslaHusk'); return; } PrimaryBeam.EndActor = Controller.Target; if( Controller!=none && KFDoorMover(Controller.Target)!=none ) { PrimaryBeam.EffectEndTime = Level.TimeSeconds + 1.0; Controller.Target.TakeDamage(22,Self,Location,vect(0,0,0), MyDamageType); return; } PrimaryBeam.EffectEndTime = Level.TimeSeconds + 2.5; GotoState('Shooting'); } simulated function Tick( float Delta ) { if ( Role < ROLE_Authority ) { if ( bDecapitated && Health > 0 && DecapitationSparks == none ) { SpawnDecapitationEffects(); } } Super(NiceMonster).Tick(Delta); if ( Role == ROLE_Authority ) { if ( Energy < EnergyMax ) Energy += EnergyRestoreRate * Delta; if ( Energy > 150 && NextHealAttemptTime < Level.TimeSeconds ) { NextHealAttemptTime = Level.TimeSeconds + 3.0; TryHealing(); } } } function TryHealing() { local Controller C; local NiceMonsterController MyMC; local NiceZombieTeslaHusk BestPatient; local bool bAnyHusks; MyMC = NiceMonsterController(Controller); if ( MyMC == none ) return; // just in case if ( MyMC.Enemy != none && VSizeSquared(MyMC.Enemy.Location - Location) < MaxPrimaryBeamRangeSquared ) return; // no healing when need to fight for ( C=Level.ControllerList; C!=none; C=C.NextController ) { if ( NiceZombieTeslaHusk(C.Pawn) != none && C.Pawn != self && C.Pawn.Health > 0 ) { bAnyHusks = true; if ( (BestPatient == none || BestPatient.Health > C.Pawn.Health) && VSizeSquared(C.Pawn.Location - Location) < MaxPrimaryBeamRangeSquared ) BestPatient = NiceZombieTeslaHusk(C.Pawn); } } if ( !bAnyHusks ) NextHealAttemptTime = Level.TimeSeconds + 10.0; // no other husks on the map - so no need to do searching so often else if ( BestPatient != none ) { if ( BestPatient.Health < BestPatient.HealthMax * 0.90 ) { MyMC.Target = BestPatient; MyMC.ChangeEnemy(BestPatient, MyMC.CanSee(BestPatient)); MyMC.GotoState('RangedAttack'); LastHealTime = Level.TimeSeconds + 3.0; // do not heal until beam is spawned GotoState('Healing'); } else NextHealAttemptTime = Level.TimeSeconds + 1.0; // if there are other Tesla Husks nearby, then check their health each second } else NextHealAttemptTime = Level.TimeSeconds + 3.0; // there are other Tesla Husks on the map, but not too close } function Died(Controller Killer, class damageType, vector HitLocation) { if ( PrimaryBeam != none ) PrimaryBeam.Instigator = none; if ( DecapitationSparks != none ) DecapitationSparks.Destroy(); AmbientSound = none; super.Died(Killer, damageType, HitLocation); } simulated event PlayDying(class DamageType, vector HitLoc) { super(NiceMonster).PlayDying(DamageType, HitLoc); if ( DecapitationSparks != none ) DecapitationSparks.Destroy(); AmbientSound = none; } // instead of roaming around, activate self-destruct function RemoveHead() { Intelligence = BRAINS_Retarded; // Headless dumbasses! bDecapitated = true; DECAP = true; DecapTime = Level.TimeSeconds; bShotAnim = true; SetAnimAction('KnockDown'); Acceleration = vect(0, 0, 0); Velocity.X = 0; Velocity.Y = 0; Controller.GoToState('WaitForAnim'); NiceMonsterController(Controller).bUseFreezeHack = True; SetGroundSpeed(0); AirSpeed = 0; WaterSpeed = 0; // No more raspy breathin'...cuz he has no throat or mouth :S AmbientSound = MiscSound; // super.TakeDamage(LastDamageAmount) isn't called yet, so set self-destruct sequence only if // zed can survive the hit if( Health > LastDamageAmount && Energy > 50 ) { SpawnDecapitationEffects(); BleedOutTime = Level.TimeSeconds + BleedOutDuration; GotoState('SelfDestruct'); } PlaySound(DecapitationSound, SLOT_Misc,1.30,true,525); } simulated function Destroyed() { if ( PrimaryBeam != none ) PrimaryBeam.Destroy(); if ( DecapitationSparks != none ) DecapitationSparks.Destroy(); super.Destroyed(); } simulated function SpawnDecapitationEffects() { if (Level.NetMode == NM_DedicatedServer) return; DecapitationSparks = spawn(class'ZedBeamSparks', self,, GetBoneCoords(HeadBone).Origin, Rotation); } simulated function int DoAnimAction( name AnimName ) { // faked animation with forces to play the end of shoot animation (where Huks is putting his gun down) if ( AnimName == 'ShootBurnsEnd' ) { PlayAnim('ShootBurns'); SetAnimFrame(120, 0, 1); return 0; } return super.DoAnimAction(AnimName); } function float RangedAttackTime() { return 5.0; } // Overridden so that anims don't get interrupted on the server if one is already playing function bool IsHeadShot(vector loc, vector ray, float AdditionalScale) { local coords C; local vector HeadLoc, B, M, diff; local float t, DotMM, Distance; local int look; local bool bUseAltHeadShotLocation; local bool bWasAnimating; if (HeadBone == '') return False; // If we are a dedicated server estimate what animation is most likely playing on the client if (Level.NetMode == NM_DedicatedServer) { if (Physics == PHYS_Falling) PlayAnim(AirAnims[0], 1.0, 0.0); else if (Physics == PHYS_Walking) { // Only play the idle anim if we're not already doing a different anim. // This prevents anims getting interrupted on the server and borking things up - Ramm if( !IsAnimating(0) && !IsAnimating(1) ) { if (bIsCrouched) { PlayAnim(IdleCrouchAnim, 1.0, 0.0); } else { bUseAltHeadShotLocation=true; } } else { bWasAnimating = true; } if ( bDoTorsoTwist ) { SmoothViewYaw = Rotation.Yaw; SmoothViewPitch = ViewPitch; look = (256 * ViewPitch) & 65535; if (look > 32768) look -= 65536; SetTwistLook(0, look); } } else if (Physics == PHYS_Swimming) PlayAnim(SwimAnims[0], 1.0, 0.0); if( !bWasAnimating ) { SetAnimFrame(0.5); } } if( bUseAltHeadShotLocation ) { HeadLoc = Location + (OnlineHeadshotOffset >> Rotation); AdditionalScale *= OnlineHeadshotScale; } else { C = GetBoneCoords(HeadBone); HeadLoc = C.Origin + (HeadHeight * HeadScale * AdditionalScale * C.XAxis) -5.0*C.XAxis - 2.0*C.YAxis; } //ServerHeadLocation = HeadLoc; // Express snipe trace line in terms of B + tM B = loc; M = ray * (2.0 * CollisionHeight + 2.0 * CollisionRadius); // Find Point-Line Squared Distance diff = HeadLoc - B; t = M Dot diff; if (t > 0) { DotMM = M dot M; if (t < DotMM) { t = t / DotMM; diff = diff - (t * M); } else { t = 1; diff -= M; } } else t = 0; Distance = Sqrt(diff Dot diff); return (Distance < (HeadRadius * HeadScale * AdditionalScale)); } state Healing { ignores TryHealing; function BeginState() { //log("Entering Healing State @ " $ Level.TimeSeconds, 'TeslaHusk'); LastHealTime = Level.TimeSeconds + 3.0; // do not heal until beam is spawned } function EndState() { local name SeqName; local float AnimFrame, AnimRate; //log("Exiting Healing State @ " $ Level.TimeSeconds, 'TeslaHusk'); NextHealAttemptTime = Level.TimeSeconds + 5.0; FreePrimaryBeam(); // end shooting animation GetAnimParams(0, SeqName, AnimFrame, AnimRate); if ( SeqName == 'ShootBurns' && AnimFrame < 120 ) SetAnimAction('ShootBurnsEnd'); // faked anim Controller.Enemy = none; NiceMonsterController(Controller).FindNewEnemy(); } function SpawnTwoShots() { SpawnPrimaryBeam(); if ( Controller != none ) PrimaryBeam.EndActor = Controller.Target; PrimaryBeam.EffectEndTime = Level.TimeSeconds + 2.5; LastHealTime = Level.TimeSeconds; // start healing } function bool FlipOver() { if ( global.FlipOver() ) { GotoState(''); return true; } return false; } function DoStun(optional Pawn instigatedBy, optional Vector hitLocation, optional Vector momentum, optional class damageType, optional float headshotLevel, optional KFPlayerReplicationInfo KFPRI){ super.DoStun(instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI); GotoState(''); } function Tick(float DeltaTime) { local NiceZombieTeslaHusk Patient; local int HealthToAdd; super.Tick(DeltaTime); if ( Level.TimeSeconds >= LastHealTime+0.25 ) { if ( PrimaryBeam == none || Energy <= 0 || Level.TimeSeconds > PrimaryBeam.EffectEndTime ) { GotoState(''); return; } NextHealAttemptTime = Level.TimeSeconds + 0.25; Patient = NiceZombieTeslaHusk(PrimaryBeam.EndActor); if ( Patient == none || Patient.Health <= 0 || Patient.Health >= Patient.HealthMax ) GotoState(''); else { HealthToAdd = min(Patient.HealthMax*HealRate*(Level.TimeSeconds-LastHealTime), Patient.HealthMax - Patient.Health); if ( HealthToAdd*HealEnergyDrain > Energy ) HealthToAdd = Energy / HealEnergyDrain; Patient.Health += HealthToAdd; Energy -= HealthToAdd*HealEnergyDrain; LastHealTime = Level.TimeSeconds; } } }} // todo: make custom controller, moving states there state Shooting { ignores TryHealing; function BeginState() { //log("Entering Shooting State @ " $ Level.TimeSeconds, 'TeslaHusk'); if ( PrimaryBeam == none ) { SpawnPrimaryBeam(); PrimaryBeam.EndActor = Controller.Target; } PrimaryBeam.EffectEndTime = Level.TimeSeconds + 2.5; BuildChain(); LastDischargeTime = Level.TimeSeconds; Discharge(DischargeRate); } function EndState() { local name SeqName; local float AnimFrame, AnimRate; //log("Exiting Shooting State @ " $ Level.TimeSeconds, 'TeslaHusk'); FreePrimaryBeam(); // end shooting animation GetAnimParams(0, SeqName, AnimFrame, AnimRate); if ( SeqName == 'ShootBurns' && AnimFrame < 120 ) SetAnimAction('ShootBurnsEnd'); // faked anim } function BuildChain() { local int ChainsRemaining; ChainRebuildTimer = default.ChainRebuildTimer; ChainsRemaining = MaxChainActors; SpawnChildBeams(PrimaryBeam, 1, ChainsRemaining); } function SpawnChildBeams(TeslaBeam MasterBeam, byte level, out int ChainsRemaining) { local Pawn P; local TeslaBeam ChildBeam; local int i; if ( MasterBeam == none || level > MaxChainLevel || ChainsRemaining <= 0 ) return; for ( i=0; i 0; ++i ) { SpawnChildBeams(MasterBeam.ChildBeams[i], level+1, ChainsRemaining); } } function ChainDamage(TeslaBeam Beam, float Damage, byte ChainLevel) { local int i; local float DmgMult; if ( Beam == none || Beam.EndActor == none || Energy < 0 || Controller == none) return; Damage = clamp(Damage, 1, Energy); // look if actor already received a damage during this discharge for ( i=0; i= Damage ) return; // Victim already received enough damage else { Damage -= DischargedActors[i].Damage; DischargedActors[i].Damage += Damage; break; } } } if ( i == DischargedActors.length ) { // new victim DischargedActors.insert(i, 1); DischargedActors[i].Victim = Beam.EndActor; DischargedActors[i].Damage = Damage; } // deal higher damage to monsters, but do not drain energy quicker DmgMult = 1.0; if ( NiceMonster(Beam.EndActor) != none ) { if ( ZombieFleshpound(Beam.EndActor) != none ) DmgMult = 20.0; else DmgMult = 3.0; } // if pawn is already chained, then damage him until he gets out of the primary range Beam.SetBeamLocation(); // ensure that StartEffect and EndEffect are set if ( VSizeSquared(Beam.EndEffect - Beam.StartEffect) <= MaxPrimaryBeamRangeSquared * ChainedBeamRangeExtension && FastTrace(Beam.EndEffect, Beam.StartEffect) ) { Beam.EndActor.TakeDamage(Damage*DmgMult, self, Beam.EndActor.Location, Beam.SetBeamRotation(), MyDamageType); if(Controller == none) return; Energy -= Damage; Damage *= ChainDamageMult; ChainLevel++; if ( Damage > 0 && ChainLevel <= MaxChainLevel) { for ( i=0; i 0; ++i ) ChainDamage(Beam.ChildBeams[i], Damage, ChainLevel); } } else { Beam.Instigator = none; // delete beam } } function Discharge(float DeltaTime) { LastDischargeTime = Level.TimeSeconds; DischargedActors.length = 0; ChainDamage(PrimaryBeam, DischargeDamage*DeltaTime, 0); if (Energy <= 0) GotoState(''); // out of energy - stop shooting } function bool FlipOver() { if ( global.FlipOver() ) { GotoState(''); return true; } return false; } function DoStun(optional Pawn instigatedBy, optional Vector hitLocation, optional Vector momentum, optional class damageType, optional float headshotLevel, optional KFPlayerReplicationInfo KFPRI){ super.DoStun(instigatedBy, hitLocation, momentum, damageType, headshotLevel, KFPRI); GotoState(''); } function Tick(float DeltaTime) { super.Tick(DeltaTime); //log("Shooting.Tick @ " $ Level.TimeSeconds $ ":" @"Energy="$Energy @"PrimaryBeam="$PrimaryBeam, 'TeslaHusk'); ChainRebuildTimer -= DeltaTime; if ( Energy <= 0 || PrimaryBeam == none || PrimaryBeam.EndActor == none || Level.TimeSeconds > PrimaryBeam.EffectEndTime ) { GotoState(''); } else if ( LastDischargeTime + DischargeRate <= Level.TimeSeconds ) { if ( ChainRebuildTimer <= 0 ) BuildChain(); Discharge(Level.TimeSeconds - LastDischargeTime); // damage chained actors } } } state SelfDestruct { ignores PlayDirectionalHit, RangedAttack, MeleeDamageTarget; function BeginState() { local NiceTeslaEMPNade MyNade; MyNade = spawn(class'NiceTeslaEMPNade', self,, Location); if ( MyNade != none ) { AttachToBone(MyNade, RootBone); MyNade.SetTimer(3.0, false); MyNade.bTimerSet = true; MyNade.Damage = max(20, Energy * 0.45); } else { // wtf? Died(LastDamagedBy.Controller,class'DamTypeBleedOut',Location); } } function bool CheckMiniFlinch(int flinchScore, Pawn instigatedBy, Vector hitLocation, Vector momentum, class damageType, float headshotLevel, KFPlayerReplicationInfo KFPRI){ return false; } function bool IsStunPossible(){ return false; } function bool CheckStun(int stunScore, Pawn instigatedBy, Vector hitLocation, Vector momentum, class damageType, float headshotLevel, KFPlayerReplicationInfo KFPRI){ return false; } function bool CanGetOutOfWay(){ return false; } } static simulated function PreCacheMaterials(LevelInfo myLevel) { myLevel.AddPrecacheMaterial(Shader'ScrnZedPack_T.TeslaHusk.TeslaHusk_SHADER'); myLevel.AddPrecacheMaterial(FinalBlend'KFZED_FX_T.Energy.ZED_FX_Beam_FB'); } defaultproperties { BeamClass=Class'ScrnZedPack.TeslaBeam' MaxPrimaryBeamRange=300.000000 MaxChildBeamRange=150.000000 ChainedBeamRangeExtension=1.200000 Energy=200.000000 EnergyMax=200.000000 EnergyRestoreRate=20.000000 DischargeDamage=20.000000 ChainDamageMult=0.700000 MyDamageType=Class'ScrnZedPack.DamTypeTesla' MaxChainLevel=5 MaxChainActors=20 DischargeRate=0.250000 HealRate=0.250000 HealEnergyDrain=0.200000 ProjectileFireInterval=5.000000 BurnDamageScale=1.000000 mind=0.000000 bFireImmune=False MoanVoice=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Talk' BleedOutDuration=5.000000 MiscSound=Sound'KF_FY_ZEDV2SND.foley.WEP_ZEDV2_Projectile_Loop' DecapitationSound=Sound'KF_FY_ZEDV2SND.Fire.WEP_ZEDV2_Secondary_Explode' MeleeAttackHitSound=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Bloat.Bloat_HitPlayer' JumpSound=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Jump' ColHeight=30.000000 ProjectileBloodSplatClass=None DetachedArmClass=Class'ScrnZedPack.SeveredArmTeslaHusk' DetachedLegClass=Class'ScrnZedPack.SeveredLegTeslaHusk' DetachedHeadClass=Class'ScrnZedPack.SeveredHeadTeslaHusk' DetachedSpecialArmClass=Class'ScrnZedPack.SeveredGunTeslaHusk' OnlineHeadshotOffset=(X=22.000000,Z=50.000000) HitSound(0)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Pain' DeathSound(0)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Death' ChallengeSound(0)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Challenge' ChallengeSound(1)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Challenge' ChallengeSound(2)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Challenge' ChallengeSound(3)=SoundGroup'KF_EnemiesFinalSnd_CIRCUS.Husk.Husk_Challenge' ScoringValue=25 GroundSpeed=100.000000 WaterSpeed=80.000000 HealthMax=800.000000 Health=800 HeadHeight=-7.500000 MenuName="Tesla Husk" AmbientSound=Sound'KF_BaseHusk_CIRCUS.Husk_IdleLoop' Mesh=SkeletalMesh'ScrnZedPack_A.TeslaHuskMesh' Skins(0)=Shader'ScrnZedPack_T.TeslaHusk.TeslaHusk_SHADER' }