1 #include "tux.h"
2 
update()3 void WhaleState::update ()
4 {
5   if ( !enable )
6   {
7     sgCoord c ;
8     sgSetCoord ( &c, 1000000.0f, 1000000.0f, 1000000.0f, 0.0f, 0.0f, 0.0f ) ;
9     whale -> setCoord ( & c ) ;
10     return ;
11   }
12 
13 
14   float hot = getHeightAndNormal ( coord.xyz, normal ) ;
15 
16   if ( hot < -1000.0f )
17     hot = coord.xyz[2]+0.1 ;
18 
19   /*
20     While we are underground, back out along the terrain
21     surface normal.
22   */
23 
24   while ( coord.xyz[2] <= hot+2.0f && coord.xyz[2] <= 0.0f )
25   {
26     sgAddVec3 ( coord.xyz, coord.xyz, normal ) ;
27     hot = getHeightAndNormal ( coord.xyz, normal ) ;
28 
29     if ( hot < -1000.0f )
30       hot = coord.xyz[2]+0.1 ;
31   }
32 
33   if ( munch_timer > 0 )
34     munch_timer-- ;
35 
36   sgVec3 to_tux   ;
37   sgVec3 heading ;
38 
39   sgSubVec3 ( to_tux, tuxState->coord.xyz, coord.xyz ) ;
40   sgHPRfromVec3 ( heading, to_tux ) ;
41 
42   float dx = fabs ( to_tux [ 0 ] ) ;
43   float dy = fabs ( to_tux [ 1 ] ) ;
44   float dz = fabs ( to_tux [ 2 ] ) ;
45 
46   float range = sqrt ( dx * dx + dy + dy ) ;
47 
48   if ( ! currState->freeze_baddies && munch_timer <= 0 &&
49          dx < 2.0 && dy < 2.0 && dz < 2.0 )
50   {
51     sgSetVec3 ( velocity, 0.0f, -0.1f, 0.0f ) ;
52     sound->playSfx ( SOUND_OW ) ;
53     tuxState -> ouch () ;
54     munch_timer = 100 ;
55   }
56 
57   /*
58     If we are in nice deep water (at least 20 meters below)
59     then we have the luxury of chasing Tux. If Tux isn't
60     in the water then we can at least stretch our flukes
61     with a nice fast run.
62   */
63 
64   if ( hot+10.0f < coord . xyz[2] )
65   {
66     /* If tux is over water then we chase him.  */
67 
68     if ( tuxState->over_water && munch_timer <= 0 )
69     {
70       if ( range > 10.0 )
71       {
72 	coord.hpr[0] = blend_angle ( coord.hpr[0], heading[0] ) ;
73 	coord.hpr[1] = blend_angle ( coord.hpr[1], 0.0f ) ;
74 	sgSetVec3 ( velocity, 0.0f, 0.5f, 0.0f ) ;
75       }
76       else
77       {
78 	sgSetVec3 ( velocity, 0.0f, range/10.0f + 0.1, 0.0f ) ;
79 
80 	coord.hpr[0] = heading[0] ;
81 	coord.hpr[1] = blend_angle ( coord.hpr[1], -heading[1] ) ;
82 
83 	if ( dx < 1.0  && dy < 1.0 && dz < 1.0 )
84 	  sgSetVec3 ( velocity, 0.0f, -0.1f, 0.0f ) ;
85       }
86     }
87     else
88       sgSetVec3 ( velocity, 0.0f, 0.5f, 0.0f ) ;
89   }
90   else
91   {
92     /*
93       We are in shallow water - let's try to get back
94       into deeper water.
95     */
96 
97     int tquad ;
98     int oquad ;
99 
100     /*
101       Figure out which quadrant the normal is pointing
102       towards:
103 			    |
104 			 1  |  0
105 		      ______|______
106 			    |
107 			 2  |  3
108 			    |
109     */
110 
111     if ( normal [ 0 ] > 0 )
112       if ( normal [ 1 ] > 0 ) tquad = 0 ; else tquad = 3 ;
113     else
114       if ( normal [ 1 ] > 0 ) tquad = 1 ; else tquad = 2 ;
115 
116     /*
117       Figure out which quadrant the whale is pointing towards...
118     */
119 
120     while ( coord.hpr[0] < 0.0f )
121       coord.hpr [ 0 ] += 360.0f ;
122 
123     int heading = (int) coord.hpr [ 0 ] % 360 ;
124 
125     if ( heading <  90 ) oquad = 1 ; else
126     if ( heading < 180 ) oquad = 2 ; else
127     if ( heading < 270 ) oquad = 3 ; else oquad = 0 ;
128 
129     if ( oquad == 0 && tquad == 3 ) tquad = -1 ;
130     if ( oquad == 3 && tquad == 0 ) tquad =  4 ;
131 
132     if ( oquad == tquad )
133       sgSetVec3 ( velocity, 0.0f, 0.5f,-0.1f ) ;
134     else
135     if ( oquad+1 == tquad )
136     {
137       coord.hpr[0] += 2.0 ;
138       sgSetVec3 ( velocity, 0.0f, 0.2f, 0.0f ) ;
139     }
140     else
141     if ( oquad-1 == tquad )
142     {
143       coord.hpr[0] -= 2.0 ;
144       sgSetVec3 ( velocity, 0.0f, 0.2f, 0.0f ) ;
145     }
146     else
147     {
148       coord.hpr[0] -= 3.0 ;
149       sgSetVec3 ( velocity, 0.0f, 0.03f,
150 		       (coord.xyz[2] >= 0.0) ? -0.1 : 0.2f ) ;
151     }
152 
153     coord.hpr[1] = blend_angle ( coord.hpr[1], 0.0f ) ;
154   }
155 
156   sgMat4 mat ;
157   sgMakeCoordMat4 ( mat, &coord ) ;
158 
159   if ( ! currState->freeze_baddies )
160   {
161     sgXformPnt3 ( coord.xyz, velocity, mat ) ;
162 
163     if ( coord.xyz[2] > 0.0f )
164       coord.xyz[2] = 0.0f ;
165   }
166 
167   whale -> setCoord ( & coord ) ;
168   whale -> update () ;
169   dcs -> setTransform ( & coord ) ;
170 }
171 
172