// // CPT operator / SondeerGame // This source file is (c) by Deltares. // - October 2014 // //============================================================================= // (Sea)Gulls, animated, making sounds, and navigating through the sky // following FlyingPathNodes in the map. // ------------------------------------------------------------ // Created by Maarten Wesselius // © 2007, Geodelft // // Date Id Modification // 2007-10-11 Wsl Class created // 2007-11-01 Wsl Sound functionality moved to GeoTimedSoundObject //============================================================================= class GeoGull extends GeoAnimal; var name NeckAnim; var name NoseAnim; var name ScratchAnim; var name DanceAnim; //var GeoTimedSoundObject soundObject; var (Sound) float AverageSecondsBetween; var (Sound) float MaxDeviation; var Vector OldLocation; // Previous location; to determine if stuck. var array Nodes; // All FlyingPathNodes in the level var int MaxDistance; // maximum distance to new target node var float idletime; var float totaltime; event PreBeginPlay() { //SetTimer(timerInterval, true); //determineNextWaitingTime(1.0); InitSound(); } //============================================================================= // Init sound object, associated sounds and configurable sound variables. // // Date Id Modification // 2006-10-11 Wsl Created this header //============================================================================= function InitSound() { /* local array arr; soundObject = Spawn(class'GeoTimedSoundObject', self); soundObject.SetAverageSecondsBetween(AverageSecondsBetween); soundObject.SetMaxDeviation(MaxDeviation); arr.length = 6; arr[0]=Sound'GeoNatureSounds.birds.gull1'; arr[1]=Sound'GeoNatureSounds.birds.gull2'; arr[2]=Sound'GeoNatureSounds.birds.gull3'; arr[3]=Sound'GeoNatureSounds.birds.gull4'; arr[4]=Sound'GeoNatureSounds.birds.gull5'; arr[5]=Sound'GeoNatureSounds.birds.gull6'; soundObject.SetSounds(arr); */ } //============================================================================= // to make sure an AIController is spawned for this GeoGull. // also, initializes the Nodes-array with all FlyingPathNodes in the Map, // initializes rotation and speed values, and sets a first target. // // Date Id Modification // 2007-10-? Jln Created code for GeoAIBird // 2007-10-25 Wsl Adapted to GeoGull //============================================================================= event PostBeginPlay() { local FlyingPathNode NP; GotoState('Flapping'); Super.PostBeginPlay(); if ( ( ControllerClass != None ) && ( Controller == None ) ) Controller = spawn( ControllerClass ); if ( Controller != None ) Controller.Possess( self ); MovementAnims[0] = 'wingflap'; MovementAnims[1] = 'wingflap'; MovementAnims[2] = 'wingflap'; MovementAnims[3] = 'wingflap'; forEach AllActors( class'FlyingPathNode', NP) { Nodes.Insert(0,1); Nodes[0] = NP; } DetermineNewTarget( self ); OldLocation = Location; MaxDistance = 10240; RotationRate.Yaw = 2500; RotationRate.Roll = -20000; totaltime = 0; /// Set timer, to be called at maximum of 3 seconds, and only ONCE. SetTimer( FRand()*3, false ); } function Timer() { GotoState('Flapping'); } //============================================================================= // called when the gull reached its target (a FlyingPathNode). The Gull // selects a new FlyingPathNode randomly, except that it's also based on distance. // // Date Id Modification // 2007-10-? Jln Created code for GeoAIBird // 2007-10-25 Wsl Adapted to GeoGull //============================================================================= function bool DetermineNewTarget( Actor OldTarget ) { local Actor NewTarget; local int index, tries; local bool found; //log(""); //log("reached destination! (OldTarget = "@OldTarget); found = false; index = Rand(Nodes.length); NewTarget = Nodes[index]; tries = 0; while(tries < 20 && OldTarget != NewTarget && VSize(NewTarget.Location - Location) > MaxDistance) { index = Rand(Nodes.length); NewTarget = Nodes[index]; totaltime = 0; tries++; } //Log("index = "@index@"; new target is "@NewTarget); Controller.MoveTarget = NewTarget; Controller.Destination = NewTarget.Location; Controller.FocalPoint = NewTarget.Location; Controller.Focus = NewTarget; found = true; if (FRand() >= 0.6) { idletime = 0; GotoState('Turn'); } else { GotoState('Flapping'); } return found; } //============================================================================= // called every game tick. It sees if it has reached it's destination, and if // so, looks for a new one. // // Date Id Modification // 2007-10-? Jln Created code for GeoAIBird // 2007-10-25 Wsl Adapted to GeoGull //============================================================================= function Tick( float DeltaTime ) { local bool found; found = false; Velocity = AirSpeed * vector( Rotation ); Acceleration = Velocity; if(Controller.MoveTarget != None) { if (found == false && VSize( Controller.MoveTarget.Location - Location ) < 200) found = DetermineNewTarget( Controller.MoveTarget ); if (found == false && VSize( OldLocation - Location ) < 48) found = DetermineNewTarget( Controller.MoveTarget ); } idletime += DeltaTime; totaltime += DeltaTime; if (idletime >= RandRange(5,8)) { GotoState('Flapping'); } //if ( self.IsInState('Turn') && FRand() > 0.98) GotoState('Flapping'); //Log(totaltime); if (totaltime > 14 + RandRange(3,6)) { found = DetermineNewTarget( Controller.MoveTarget ); totaltime = 0; } } /* hoe werkt dit??? simulated event AnimEnd(int Channel) { local int wingflap; Super.AnimEnd(Channel); log("AnimEnd()!~!!!! Instance = "@ self @", Channel = "@Channel); MovementAnims[0]=FlyIdle; wingflap = Rand(4); if(wingflap == 0) { MovementAnims[0]=FlyingAnims[0]; } } */ state() Turn { event AnimEnd( int Channel ) { } Begin: Sleep(FRand()*2); PlayAnim('Idle', 1); MovementAnims[0] = 'Idle'; MovementAnims[1] = 'Idle'; MovementAnims[2] = 'Idle'; MovementAnims[3] = 'Idle'; } state() Flapping { event AnimEnd( int Channel ) { } Begin: //log("Flapping state!"); Sleep(FRand()*2); PlayAnim('wingflap', 1); MovementAnims[0] = 'wingflap'; MovementAnims[1] = 'wingflap'; MovementAnims[2] = 'wingflap'; MovementAnims[3] = 'wingflap'; } state() Idle { event AnimEnd( int Channel ) { } Begin: //log("Flapping state!"); Sleep(FRand()*2); PlayAnim('wingflap', 1); MovementAnims[0] = 'wingflap'; MovementAnims[1] = 'wingflap'; MovementAnims[2] = 'wingflap'; MovementAnims[3] = 'wingflap'; } defaultproperties { Mesh=SkeletalMesh'AnimalA.Meeuw' TransientSoundRadius=64.0 TransientSoundVolume=1.0 AverageSecondsBetween=6.0 MaxDeviation=3.0 MovementAnims(0)="wingflap" MovementAnims(1)="wingflap" MovementAnims(2)="wingflap" MovementAnims(3)="wingflap" RunningAnims(0)="wingflap" RunningAnims(1)="wingflap" RunningAnims(2)="wingflap" RunningAnims(3)="wingflap" WalkingAnims(0)="wingflap" WalkingAnims(1)="wingflap" WalkingAnims(2)="wingflap" WalkingAnims(3)="wingflap" CrouchAnims(0)="Idle" CrouchAnims(1)="Idle" CrouchAnims(2)="Idle" CrouchAnims(3)="Idle" FlyingAnims(0)="Idle" FlyingAnims(1)="Idle" FlyingAnims(2)="Idle" FlyingAnims(3)="Idle" SwimmingAnims(0)="wingflap" SwimmingAnims(1)="wingflap" SwimmingAnims(2)="wingflap" SwimmingAnims(3)="wingflap" TurnLeftAnim="wingflap" TurnRightAnim="wingflap" StandingTurnAnims(0)="wingflap" StandingTurnAnims(1)="wingflap" CrouchTurnAnims(0)="wingflap" CrouchTurnAnims(1)="wingflap" StandIdle="Idle" CrouchIdle="Idle" FlyIdle="Idle" SwimIdle="Idle" JumpStandingAnim="wingflap" JumpMovingAnim="wingflap" LandAnim="wingflap" FallingAnim="wingflap" NeckAnim="Idle" NoseAnim="Idle" ScratchAnim="Idle" DanceAnim="Idle" BaseEyeHeight=16 CollisionRadius=+00032.000000 CollisionHeight=15.000000 CrouchHeight=+12.0 WalkingPct=+0.2 DrawScale=0.25 AirSpeed=500.000000 Physics=PHYS_Flying bReplicateAnimations=True bCollideActors=false }