//============================================================================= // NaliProphet - mesh and skin created by Turboman // // coded by Asgard // http://www.angelfire.com/empire/napali/ http://ammo.at/napali // Modified by Marco, use QueenDests. //============================================================================= class NaliProphet expands FSPawn; #exec AUDIO IMPORT FILE="SOUNDS\naliprophet\scaryN2.WAV" NAME="scaryN2" GROUP="NaliProphet" var() bool bKAMIKAZE; var bool bUseQueenDests; var float LastDuckTime; var() int SlamDamage; var vector TelepDest; var NavigationPoint LastNav; var transient float TeleportTime; var() bool bPropCanTeleport; var()class MeleeEffect; var() float deathdelay; var() vector lightningoffset; var() vector orboffset; var(Sounds) sound slam; var(Sounds) sound ExplodeSound; var byte row; var int laststun, Pathcount; var() float Stunfreq; // How often the NaliProphet can be stunned after health 50% // random also involved. default every 10 game seconds var() name StatueFreeTag; var name InitialTag; function PostBeginPlay() { local NavigationPoint N; InitialTag = Tag; for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { if( QueenDest(N)!=None ) { bUseQueenDests = true; break; } } for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { if( !bUseQueenDests || QueenDest(N)!=None ) Pathcount++; } laststun = Level.TimeSeconds; super.PostBeginPlay(); } function PreSetMovement() { MaxDesiredSpeed = 0.6 + 0.13 * skill; bCanJump = true; bCanWalk = false; bCanSwim = true; bCanFly = true; MinHitWall = -0.6; if (Intelligence > BRAINS_Reptile) bCanOpenDoors = true; if (Intelligence > BRAINS_Reptile) bCanDoSpecial = true; bCanDuck = true; } function SetMovementPhysics() { if (Region.Zone.bWaterZone) SetPhysics(PHYS_Swimming); else SetPhysics(PHYS_Flying); } event bool EncroachingOn( actor Other ) { if ( (Other.Brush != None) || (Brush(Other) != None) ) return true; return false; } function TweenToFighter(float tweentime) { TweenAnim('Fly', tweentime); } function TweenToRunning(float tweentime) { if ( (AnimSequence != 'Fly') || !bAnimLoop ) TweenAnim('Fly', tweentime); } function TweenToWalking(float tweentime) { if ( (AnimSequence != 'Fly') || !bAnimLoop ) TweenAnim('Fly', tweentime); } function TweenToWaiting(float tweentime) { TweenAnim('IDLE', tweentime); } function TweenToPatrolStop(float tweentime) { TweenAnim('Fly', tweentime); } function PlayRunning() { LoopAnim('Fly', -1.0/AirSpeed,, 0.4); } function PlayWalking() { LoopAnim('Fly', -1.0/AirSpeed,, 0.4); } function PlayChallenge() { local float decision; local float animspeed; animspeed = 0.4 + 0.6 * FRand(); decision = FRand(); if (decision < 0.3) NextAnim = 'IDLE'; else if (decision < 0.7) { NextAnim = 'laugh'; } else { NextAnim = 'Cutthroat'; } LoopAnim(NextAnim, animspeed); } function PlayThreatening() { PlayChallenge(); } function PlayTurning() { LoopAnim('Fly', -1.0/AirSpeed,, 0.4); } function PlayGutHit(float tweentime) { TweenAnim( 'GutHit', tweentime ); } function PlayHeadHit(float tweentime) { TweenAnim( 'HeadHit', tweentime ); } function PlayLeftHit(float tweentime) { TweenAnim( 'TakeDamage', tweentime ); } function PlayRightHit(float tweentime) { TweenAnim( 'TakeDamage', tweentime ); } function PlayWaiting() { local float decision; local float animspeed; animspeed = 0.4 + 0.3 * FRand(); decision = FRand(); if (decision < 0.75) NextAnim = 'IDLE'; else if (decision < 0.8) { NextAnim = 'Fist'; } else if (decision < 0.85) { NextAnim = 'meditate'; } else if (decision < 0.9) { NextAnim = 'pray'; } else if (decision < 0.95) { NextAnim = 'cough'; } else { NextAnim = 'sweat'; } if ( AnimSequence == NextAnim ) LoopAnim(NextAnim, animspeed); else PlayAnim(NextAnim, animspeed, 0.25); } function PlayPatrolStop() { PlayWaiting(); } function PlayWaitingAmbush() { PlayWaiting(); } function PlayDying(name DamageType, vector HitLoc) { PlaySound(Die, SLOT_Talk, 4 * TransientSoundVolume); if ( Velocity.Z > 250 ) { playanim('death'); return; } if ( FRand() < 0.7 ) playanim('deatha'); else playanim('deathc'); } function TweenToFalling() { TweenAnim('Fly', 0.2); } function PlayInAir() { LoopAnim('Fly'); } function PlayLanded(float impactVel) { PlayAnim('Fly'); } function PlayVictoryDance() { PlayAnim('fist', 0.6, 0.1); } function PlayMeleeAttack() { PlayAnim('ATTACK4'); } function SlamDamageTarget() { local pawn aPawn; local vector X,Y,Z, Start; MakeNoise(1.0); GetAxes(Rotation,X,Y,Z); Start = Location + 1.2 * CollisionRadius * X; if(health>0 && !bDeleteme) spawn(MeleeEffect ,self,'',Start); for (aPawn=level.pawnlist;aPawn!=none;aPawn=aPawn.nextpawn) { if(aPawn!=self) ThrowOther(aPawn); } if ( Target == None ) return; if(MeleeDamageTarget( SlamDamage, ( 70000 * Normal( Target.Location - Location ))) ) { PlaySound(Slam, SLOT_Interact); PlaySound(Slam, SLOT_Misc); } } function PlayRangedAttack() { local float dist; local vector Dir; if (target==none) { PlayRunning(); return; } Dir = Target.Location - Location; dist = VSize(Dir); if ( FRand() < 0.3 && dist < 2000 && !Region.Zone.bWaterZone) PlayAnim('ATTACK5'); else if ( FRand() < 0.6 ) PlayAnim('ATTACK2'); else { row = 0; PlayAnim('ATTACK3'); } } function PlayMovingAttack() { PlayRangedAttack(); } function SpawnShot() { local vector X,Y,Z, projStart; GetAxes(Rotation,X,Y,Z); if (row == 0) MakeNoise(1.0); projStart = Location + 1 * CollisionRadius * X + ( 0.7 - 0.2 * row) * CollisionHeight * Z + 0.2 * CollisionRadius * Y; spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 400 * (4 - row)/(3.5-skill), false, bWarnTarget)); projStart = Location + 1 * CollisionRadius * X + ( 0.7 - 0.2 * row) * CollisionHeight * Z - 0.2 * CollisionRadius * Y; spawn(RangedProjectile ,self,'',projStart,AdjustAim(ProjectileSpeed, projStart, 400 * (4 - row)/(3.5-skill), true, bWarnTarget)); row++; } function sphere() { local vector X,Y,Z, projStart; local rotator projRotation; local float dist; local vector Dir; if (target==none) return; Dir = Target.Location - Location; dist = VSize(Dir); MakeNoise(1.0); GetAxes(Rotation,X,Y,Z); projStart = Location + orboffset.X * CollisionRadius * X + orboffset.Y * CollisionRadius * Y + orboffset.Z * CollisionRadius * Z; if (FRand() < 0.5 && dist < 2000 && !Region.Zone.bWaterZone) { projRotation = AdjustToss( ProjectileSpeed, projStart, 200, bLeadTarget, true ); spawn(class'naliorb' ,self,'',projStart,projRotation); } else { projRotation = AdjustAim(ProjectileSpeed, projStart, 400, bLeadTarget, true); spawn(class'nalisphere' ,self,'',projStart,projRotation); } } function rotator AdjustToss( float ProjSpeed, vector ProjStart, int AimError, bool LeadTarget, bool WarnTarget ) { local rotator FireRotation; local vector FireSpot; local actor HitActor; local vector HitLocation, HitNormal; local float TargetDist, TossSpeed, TossTime; if( projSpeed == 0 ) return AdjustAim( projSpeed, projStart, aimerror, leadTarget, warnTarget ); if( Target == None ) Target = Enemy; if( Target == None ) return Rotation; if( !Target.IsA('Pawn') ) return rotator( Target.Location - Location ); FireSpot = Target.Location; TargetDist = VSize( Target.Location - ProjStart ); if ( leadTarget ) { FireSpot += FMin( 1, 0.7 + 0.6 * FRand() ) * ( Target.Velocity * TargetDist / ProjSpeed ); HitActor = Trace( HitLocation, HitNormal, FireSpot, ProjStart, false ); if( HitActor != None ) { FireSpot = 0.5 * ( FireSpot + Target.Location ); } } //try middle FireSpot.Z = Target.Location.Z; HitActor = Trace( HitLocation, HitNormal, FireSpot, ProjStart, false ); if ( HitActor != None && Target == Enemy ) { FireSpot = LastSeenPos; if( Location.Z >= LastSeenPos.Z ) { FireSpot.Z -= 0.5 * Enemy.CollisionHeight; } } // adjust for toss distance (assume 200 z velocity add & 60 init height) if( FRand() < 0.90 ) { TossSpeed = ProjSpeed + 0.4 * VSize( Velocity ); if( Region.Zone.ZoneGravity.Z != Region.Zone.Default.ZoneGravity.Z || TargetDist > TossSpeed ) { TossTime = TargetDist / TossSpeed; FireSpot.Z -= ( ( 0.25 * Region.Zone.ZoneGravity.Z * TossTime + 200 ) * TossTime + 0.4 * CollisionHeight ); } } FireRotation = Rotator( FireSpot - ProjStart ); FireRotation.Yaw = FireRotation.Yaw + ( Rand(2 * AimError) - AimError ); if( WarnTarget && Pawn(Target) != None ) Pawn(Target).WarnTarget( self, ProjSpeed, Vector(FireRotation) ); FireRotation.Yaw = FireRotation.Yaw & 65535; if( Abs( FireRotation.Yaw - ( Rotation.Yaw & 65535 ) ) > 8192 && Abs( FireRotation.Yaw - ( Rotation.Yaw & 65535 ) ) < 57343 ) { if( FireRotation.Yaw > Rotation.Yaw + 32768 || FireRotation.Yaw < Rotation.Yaw && FireRotation.Yaw > Rotation.Yaw - 32768 ) { FireRotation.Yaw = Rotation.Yaw - 8192; } else { FireRotation.Yaw = Rotation.Yaw + 8192; } } ViewRotation = FireRotation; return FireRotation; } function lightning() { local vector X,Y,Z, projStart; local rotator projRotation; local lightningbolt lb; MakeNoise(1.0); GetAxes(Rotation,X,Y,Z); projStart = Location + lightningoffset.X * CollisionRadius * X + lightningoffset.Y * CollisionRadius * Y + lightningoffset.Z * CollisionRadius * Z; projRotation = AdjustAim(1000000, projStart, 1000, bLeadTarget, true); lb=spawn(class'lightningbolt' ,self,'',projStart,projRotation); } function TryToDuck(vector duckDir, bool bReversed) { local vector HitLocation, HitNormal, Extent; local bool duckLeft, bSuccess; local actor HitActor; if ( Health <=0 || bDeleteme ) return; if ( Level.TimeSeconds - LastDuckTime < 0.6 - 0.1 * skill ) return; if ( Region.Zone.bWaterZone ) return; duckLeft = !bReversed; Extent.X = CollisionRadius; Extent.Y = CollisionRadius; Extent.Z = CollisionHeight; if ( (Physics != PHYS_Flying) && (FRand() < 0.4) ) // try to duck up { HitActor = Trace(HitLocation, HitNormal, Location + vect(0,0,300), Location, false, Extent); if ( HitActor == None ) { PlayAnim('Fly', 1.6, 0.1); SetPhysics(PHYS_Flying); Destination = Location + vect(0,0,300); Velocity = AirSpeed * vect(0,0,1); LastDuckTime = Level.TimeSeconds; GotoState('TacticalMove', 'DoMove'); return; } } HitActor = Trace(HitLocation, HitNormal, Location + 200 * duckDir, Location, false, Extent); bSuccess = ( HitActor == None ); if ( !bSuccess ) { duckLeft = !duckLeft; duckDir *= -1; HitActor = Trace(HitLocation, HitNormal, Location + 200 * duckDir, Location, false, Extent); bSuccess = ( HitActor == None ); } if ( !bSuccess ) return; LastDuckTime = Level.TimeSeconds; if ( duckLeft ) PlayAnim('DodgeL'); else PlayAnim('DodgeR'); SetPhysics(PHYS_Flying); Destination = Location + 200 * duckDir; Velocity = AirSpeed * duckDir; GotoState('TacticalMove', 'DoMove'); } state TacticalMove { ignores SeePlayer, HearNoise; function PickDestination(bool bNoCharge) { if ( FRand() < 0.2 && level.TimeSeconds>TeleportTime && bPropCanTeleport && (Pathcount>20 || bUseQueenDests) ) GotoState('Teleporting'); else Super.PickDestination(bNoCharge); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.2 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state Hunting { ignores EnemyNotVisible; function PickDestination() { if ( level.TimeSeconds>TeleportTime && bPropCanTeleport && (Pathcount>20 || bUseQueenDests) ) GotoState('Teleporting'); else super.PickDestination(); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.2 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } State Teleporting { ignores TakeDamage, SeePlayer, EnemyNotVisible, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, Died; function Tick(float DeltaTime) { if ( Style == STY_Translucent ) { ScaleGlow -= 3 * DeltaTime; if ( ScaleGlow < 0.3 ) { Spawn(class'NPteleport',,, location); if( Location!=TelepDest ) Spawn(class'NPteleport',,, TelepDest); if( SetLocation(TelepDest) && Enemy!=None ) { DesiredRotation = rotator(Enemy.Location - TelepDest); DesiredRotation.Pitch = 0; setRotation(DesiredRotation); } PlaySound(sound'Teleport1', SLOT_Interface); GotoState('Attacking'); } } else { Fatness = Max(0, Fatness - 100*DeltaTime); if ( Fatness < 80 ) { bUnlit = true; ScaleGlow = 2.0; Style = STY_Translucent; } } } function BeginState() { local NavigationPoint Nav, Best; local float rating, BestRating, Dist, nDist; local byte maxcount; Acceleration = Vect(0,0,0); if( Enemy!=none ) { for ( Nav=Level.NavigationPointList; Nav!=None; Nav=Nav.NextNavigationPoint ) { if( bUseQueenDests && QueenDest(Nav)==None ) continue; rating = 0; Dist = VSize(Nav.Location - Enemy.Location); if( Enemy.LineOfSightTo(Nav) ) { maxcount++; Rating = Dist; Rating+=Rand(5000); if(Dist >5000) Rating+=3000; else if(Dist <50) Rating+=3000; if( LastNav==Nav) Rating+=100000; else if(LastNav!=none) { nDist = VSize(Nav.Location-LastNav.Location); if(nDist <500) Rating+=3000; } } else rating+=(Dist*2.f); if ( Best==None || Rating10 ) break; } } LastNav = Best; TelepDest = Best.location; } else GotoState('Attacking'); } function EndState() { bUnlit = false; Style = STY_Normal; ScaleGlow = 1.0; Fatness = Default.Fatness; TeleportTime = level.TimeSeconds+5.f; } } function Died(pawn Killer, name damageType, vector HitLocation) { if ( bKAMIKAZE ) { PlayAnim('KAMIKAZE'); GotoState('Exploding'); } else Super.Died(Killer, damageType, HitLocation); } state Exploding { ignores TakeDamage, SeePlayer, EnemyNotVisible, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, Died; function Destroyed() { MakeNoise(1.0); SpawnGibbedCarcass(); Global.Destroyed(); } function effectz() { PlaySound(ExplodeSound, SLOT_None,10.0); PlaySound(ExplodeSound, SLOT_Misc,10.0); PlaySound(ExplodeSound, SLOT_Talk,10.0); Spawn(Class 'selfeffect',,, Location); } function BeginState() { bStasis = false; Acceleration = Vect(0,0,0); SetPhysics(PHYS_None); } final function SendEvent() { local Actor A; foreach AllActors( class 'Actor', A, Event ) { if (enemy!=none) A.Trigger( Self, Enemy ); else A.Trigger( Self, Self ); } } Begin: FinishAnim(); effectz(); sleep(deathdelay); if( Event != '' ) SendEvent(); Destroy(); } function Screamdeath() { playsound(Sound'UnrealShare.Nali.death1n', SLOT_None,10.0,,,0.8); playsound(Sound'UnrealShare.Nali.death1n', SLOT_Misc,10.0,,,0.8); playsound(Sound'UnrealShare.Nali.death1n', SLOT_Talk,10.0,,,0.8); } function ThrowOther(Pawn Other) { local float dist, shake; local PlayerPawn aPlayer; local vector Momentum; if ( Other.mass > 500 ) return; aPlayer = PlayerPawn(Other); if (aPlayer == None) { if (Other.Physics != PHYS_Walking) return; dist = VSize(Location - Other.Location); if (dist > 500) return; } else { dist = VSize(Location - Other.Location); shake = FMax(500, 1500 - dist); if ( dist > 1500 ) return; aPlayer.ShakeView( FMax(0, 0.35 - dist/20000), shake, 0.015 * shake); if ( (Other.Physics != PHYS_Walking) || (dist > 1500) ) return; } Momentum = -0.5 * Other.Velocity + 100 * VRand(); Momentum.Z = 7000000.0/((0.2 * dist + 50) * Other.Mass); Other.AddVelocity(Momentum); } ////////////////////////////////////////////////////////////////////////////////// state knockout { ignores SeePlayer, EnemyNotVisible, HearNoise, KilledBy, HitWall, Falling, WarnTarget, LongFall, PlayTakeHit; function AnimEnd() { if ( AnimSequence == 'Dead2A' ) { if ( Physics == PHYS_None ) PlayAnim('Dead2c', 0.7, 0.07); else Playanim('Dead2B'); } else if ( AnimSequence == 'Dead2B' ) { if ( Physics == PHYS_Falling ) Playanim('Dead2B'); else Playanim('stunned'); } else Playanim('stunned'); } singular function Landed(vector HitNormal) { local vector HitLocation; local actor HitActor; HitActor = Trace(HitLocation, HitNormal, Location - 2 * CollisionHeight * vect(0,0,1), Location, true); if (HitActor == Level) { Mass=9000.0; SetPhysics(PHYS_None); gotostate('knockout','landed'); } else { SetPhysics(PHYS_None); gotostate('knockout','Getup'); } } function Bump(actor Other) { if (Region.Zone.bWaterZone) // probablly not needed SetPhysics(PHYS_Swimming); else SetPhysics(PHYS_Flying); Velocity = -150 * normal(Other.Location - Location); gotostate('Knockout','Getup'); } function ZoneChange(ZoneInfo newZone) { if ( newZone.bWaterZone ) { super.ZoneChange(newZone); gotostate('Attacking'); } } function BeginState() { if (Region.Zone.bWaterZone) gotostate('Attacking'); } function EndState() { laststun=level.TimeSeconds; Mass=default.Mass; } Begin: Acceleration = vect(0,0,0); DesiredRotation = Rotation; DesiredRotation.Pitch = 0; setRotation(DesiredRotation); if (Physics == PHYS_Flying) { Playanim('Takedamage'); SetPhysics(PHYS_Falling); Goto('Falling'); } Landed: Disable('Landed'); PlayAnim('stunned'); sleep(2.0 + Rand(5)); Getup: Disable('AnimEnd'); Playanim('AWAKEN'); finishanim(); gotostate('Attacking'); Falling: } state MeleeAttack { ignores SeePlayer, HearNoise, Bump; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if ( Health < 0.1 * Default.Health && health > 0 && FRand() < 0.2 && instigatedBy!=none && laststun < level.TimeSeconds -6 ) { laststun = level.TimeSeconds; gotostate('knockout'); return; } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state RangedAttack { ignores SeePlayer, HearNoise, Bump; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.1 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state Roaming { ignores EnemyNotVisible; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.1 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state Charging { ignores SeePlayer, HearNoise; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.2 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state StakeOut { ignores EnemyNotVisible; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.2 &&!bDeleteMe) { gotostate('knockout'); return; } } Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } } state Wandering { ignores EnemyNotVisible; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if (!bDeleteme && Health < 0.5 * Default.Health && health > 0 && instigatedBy!=none && level.TimeSeconds-laststun>Stunfreq && !Region.Zone.bWaterZone) { laststun=level.TimeSeconds; if (FRand() < 0.2 &&!bDeleteMe) { gotostate('knockout'); return; } } } } state LiveStatue expands GameEnded { function BeginState() { local Actor A; Tag = StatueFreeTag; SetCollision(false,false,false); SetPhysics(PHYS_None); Mesh = Mesh'prophetstatue'; DrawScale = 2; bCollideWorld = false; if( AttachTag!='' ) Foreach AllActors(Class'Actor',A,AttachTag) { SetBase(A); break; } } final function vector GetRandColRange() { local vector V; V.X = CollisionRadius-(FRand()*CollisionRadius*2.f); V.Y = CollisionRadius-(FRand()*CollisionRadius*2.f); V.Z = CollisionHeight-(FRand()*CollisionHeight*2.f); return V; } final function vector GetVRandRange() { local vector V; V.X = 1.f-(FRand()*2.f); V.Y = 1.f-(FRand()*2.f); V.Z = 1.f-(FRand()*2.f); return V; } function Trigger( actor Other, pawn EventInstigator ) { local WallFragments F; local byte i; for( i=Rand(5); i<20; i++ ) { F = Spawn(Class'WallFragments',,,Location+GetRandColRange(),RotRand(true)); if( F==None ) continue; F.CalcVelocity(GetVRandRange()*600.f,0); F.Skin = Texture'FSPack.Skins.Jst2'; F.DrawScale = FRand()*0.5f+0.8f; } GoToState(,'FreeMe'); } function EndState() { Move(vect(0,0,10)); Tag = InitialTag; SetCollision(true,true,true); SetMovementPhysics(); Mesh = Default.Mesh; DrawScale = Default.DrawScale; bCollideWorld = true; } Begin: Stop; FreeMe: Sleep(0.2); Orders = ''; WhatToDoNext('',''); } defaultproperties { Health=460 DrawScale=0.75 CollisionRadius=24 CollisionHeight=57 DrawType=DT_Mesh Mesh=LodMesh'naliprophetm' bHasRangedAttack=True bMovingRangedAttack=True AirSpeed=210.000000 AccelRate=600.000000 Aggressiveness=0.800000 MeleeRange=80.000000 SlamDamage=75.000000 Slam=Sound'UnrealI.Titan.slaphit1Ti' jumpz=100.00 RangedProjectile=Class'NaliPProjectile' bCanStrafe=True bIsBoss=True CombatStyle=0.85 SightRadius=5000.000000 Mass=300.000000 Buoyancy=300.000000 bKAMIKAZE=true ExplodeSound=Sound'fspack.naliprophet.scaryN2' deathdelay=3.000000 MeleeEffect=class'FSRingExplosion2' lightningoffset=(X=2.000000,Y=0.000000,Z=2.000000) orboffset=(X=2.000000,Y=0.000000,Z=1.400000) ProjectileSpeed=1400.00 ReducedDamageType=zapped ReducedDamagePct=0.900000 Stunfreq=10.00 bPropCanTeleport=true CarcassType=Class'NprophetCarcass' }