]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIStorm.cxx
Merge branch 'next' into durk-atc
[flightgear.git] / src / AIModel / AIStorm.cxx
1 // FGAIStorm - FGAIBase-derived class creates an AI thunderstorm or cloud
2 //
3 // Written by David Culp, started Feb 2004.
4 //
5 // Copyright (C) 2004  David P. Culp - davidculp2@comcast.net
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <Main/fg_props.hxx>
26 #include <Main/globals.hxx>
27 #include <Scenery/scenery.hxx>
28 #include <string>
29 #include <math.h>
30 #include <cstdlib>
31 #include <time.h>
32
33 using std::string;
34
35 #include "AIStorm.hxx"
36
37
38 FGAIStorm::FGAIStorm() : FGAIBase(otStorm) {
39    delay = 3.6;
40    subflashes = 1;
41    timer = 0.0;
42    random_delay = 3.6;
43    flash_node = fgGetNode("/environment/lightning/flash", true);
44    flash_node->setBoolValue(false);
45    flashed = 0; 
46    flashing = false;
47    subflash_index = -1;
48    subflash_array[0] =  1;
49    subflash_array[1] =  2;
50    subflash_array[2] =  1;
51    subflash_array[3] =  3;
52    subflash_array[4] =  2;
53    subflash_array[5] =  1;
54    subflash_array[6] =  1;
55    subflash_array[7] =  2;
56
57    turb_mag_node = fgGetNode("/environment/turbulence/magnitude-norm", true);
58    turb_rate_node = fgGetNode("/environment/turbulence/rate-hz", true);
59 }
60
61
62 FGAIStorm::~FGAIStorm() {
63 }
64
65 void FGAIStorm::readFromScenario(SGPropertyNode* scFileNode) {
66   if (!scFileNode)
67     return;
68
69   FGAIBase::readFromScenario(scFileNode);
70
71   setDiameter(scFileNode->getDoubleValue("diameter-ft", 0.0)/6076.11549);
72   setHeight(scFileNode->getDoubleValue("height-msl", 5000.0));
73   setStrengthNorm(scFileNode->getDoubleValue("strength-norm", 1.0)); 
74 }
75
76 bool FGAIStorm::init(bool search_in_AI_path) {
77    return FGAIBase::init(search_in_AI_path);
78 }
79
80 void FGAIStorm::bind() {
81     FGAIBase::bind();
82 }
83
84 void FGAIStorm::unbind() {
85     FGAIBase::unbind();
86 }
87
88
89 void FGAIStorm::update(double dt) {
90    FGAIBase::update(dt);
91    Run(dt);
92    Transform();
93 }
94
95
96 void FGAIStorm::Run(double dt) {
97
98    double speed_north_deg_sec;
99    double speed_east_deg_sec;
100
101    // convert speed to degrees per second
102    speed_north_deg_sec = cos( hdg / SG_RADIANS_TO_DEGREES )
103                           * speed * 1.686 / ft_per_deg_lat;
104    speed_east_deg_sec  = sin( hdg / SG_RADIANS_TO_DEGREES )
105                           * speed * 1.686 / ft_per_deg_lon;
106
107    // set new position
108    pos.setLatitudeDeg( pos.getLatitudeDeg() + speed_north_deg_sec * dt);
109    pos.setLongitudeDeg( pos.getLongitudeDeg() + speed_east_deg_sec * dt); 
110
111    // do calculations for weather radar display 
112    UpdateRadar(manager);
113
114    // **************************************************
115    // *     do lightning                               *
116    // **************************************************
117
118    if (timer > random_delay) {
119      srand((unsigned)time(0));
120      random_delay = delay + (rand()%3) - 1.0;
121      //cout << "random_delay = " << random_delay << endl;
122      timer = 0.0;
123      flashing = true;
124      subflash_index++;
125      if (subflash_index == 8) subflash_index = 0; 
126      subflashes = subflash_array[subflash_index]; 
127    }
128
129    if (flashing) {
130      if (flashed < subflashes) {
131          timer += dt;
132          if (timer < 0.1) { 
133          flash_node->setBoolValue(true);
134          } else {
135             flash_node->setBoolValue(false);
136             if (timer > 0.2) {
137               timer = 0.0;
138               flashed++;
139             }
140          }
141      } else {
142        flashing = false;
143        timer = 0.0;
144        flashed = 0;
145      }
146    }
147    else {
148      timer += dt;
149    }  
150
151    // ***************************************************
152    // *      do turbulence                              *
153    // ***************************************************
154
155    // copy user's position from the AIManager
156    double user_latitude  = manager->get_user_latitude();
157    double user_longitude = manager->get_user_longitude();
158    double user_altitude  = manager->get_user_altitude();
159
160    // calculate range to target in feet and nautical miles
161    double lat_range = fabs(pos.getLatitudeDeg() - user_latitude) * ft_per_deg_lat;
162    double lon_range = fabs(pos.getLongitudeDeg() - user_longitude) * ft_per_deg_lon;
163    double range_ft = sqrt(lat_range*lat_range + lon_range*lon_range);
164    range = range_ft / 6076.11549;
165
166    if (range < (diameter * 0.5) &&
167        user_altitude > (altitude_ft - 1000.0) &&
168        user_altitude < height) {
169               turb_mag_node->setDoubleValue(strength_norm);
170               turb_rate_node->setDoubleValue(0.5);
171    } 
172      
173 }
174