From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_nav_a_i_8cpp_source.html | 739 +++++++++++++++++++++++++++++ 1 file changed, 739 insertions(+) create mode 100644 Doc/doxygen/html/_nav_a_i_8cpp_source.html (limited to 'Doc/doxygen/html/_nav_a_i_8cpp_source.html') diff --git a/Doc/doxygen/html/_nav_a_i_8cpp_source.html b/Doc/doxygen/html/_nav_a_i_8cpp_source.html new file mode 100644 index 0000000..ffaae07 --- /dev/null +++ b/Doc/doxygen/html/_nav_a_i_8cpp_source.html @@ -0,0 +1,739 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/NavAI.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
NavAI.cpp
+
+
+Go to the documentation of this file.
1 /* Project Starshatter 5.0
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2007. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Stars.exe
+
6  FILE: NavAI.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Automatic Navigator Artificial Intelligence class
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "NavAI.h"
+
17 #include "TacticalAI.h"
+
18 #include "Instruction.h"
+
19 #include "NavSystem.h"
+
20 #include "QuantumDrive.h"
+
21 #include "Ship.h"
+
22 #include "ShipDesign.h"
+
23 #include "ShipCtrl.h"
+
24 #include "Drive.h"
+
25 #include "Farcaster.h"
+
26 #include "Shield.h"
+
27 #include "Sim.h"
+
28 #include "StarSystem.h"
+
29 #include "KeyMap.h"
+
30 #include "HUDView.h"
+
31 #include "HUDSounds.h"
+
32 
+
33 #include "Game.h"
+
34 
+
35 // +----------------------------------------------------------------------+
+
36 
+ +
38 : ShipAI(s), complete(false), brakes(0),
+
39 drop_state(0), quantum_state(0), farcaster(0), terrain_warning(false)
+
40 {
+
41  seek_gain = 20;
+
42  seek_damp = 0.55;
+
43 
+
44  delete tactical;
+
45  tactical = 0;
+
46 }
+
47 
+
48 // +--------------------------------------------------------------------+
+
49 
+ +
51 { }
+
52 
+
53 // +--------------------------------------------------------------------+
+
54 
+
55 void
+ +
57 {
+
58  if (!ship) return;
+
59 
+
60  seconds = s;
+
61 
+
62  ship->SetDirectorInfo(" ");
+
63 
+ +
65  takeoff = true;
+
66 
+
67  else if (takeoff && ship->MissionClock() > 10000)
+
68  takeoff = false;
+
69 
+
70  FindObjective();
+
71  Navigator();
+
72 
+
73  // watch for disconnect:
+ +
75  NavSystem* navsys = ship->GetNavSystem();
+
76  if (navsys) {
+ +
78  navsys->DisengageAutoNav();
+
79 
+
80  Sim* sim = Sim::GetSim();
+
81  if (sim) {
+
82  ship->SetControls(sim->GetControls());
+
83  return;
+
84  }
+
85  }
+
86  }
+
87 
+
88  static double time_til_change = 0.0;
+
89 
+
90  if (time_til_change < 0.001) {
+
91  if (ship->GetShield()) {
+
92  Shield* shield = ship->GetShield();
+
93  double level = shield->GetPowerLevel();
+
94 
+ + +
97  shield->SetPowerLevel(100);
+
98  time_til_change = 0.5f;
+
99  }
+
100 
+ + +
103  shield->SetPowerLevel(0);
+
104  time_til_change = 0.5f;
+
105  }
+
106 
+
107  else if (ShipCtrl::KeyDown(KEY_SHIELDS_UP)) {
+
108  if (level < 25) level = 25;
+
109  else if (level < 50) level = 50;
+
110  else if (level < 75) level = 75;
+
111  else level = 100;
+
112 
+ +
114  shield->SetPowerLevel(level);
+
115  time_til_change = 0.5f;
+
116  }
+
117 
+ +
119  if (level > 75) level = 75;
+
120  else if (level > 50) level = 50;
+
121  else if (level > 25) level = 25;
+
122  else level = 0;
+
123 
+ +
125  shield->SetPowerLevel(level);
+
126  time_til_change = 0.5f;
+
127  }
+
128 
+
129  }
+
130  }
+
131  else {
+
132  time_til_change -= seconds;
+
133  }
+
134 
+ +
136  ship->FireDecoy();
+
137 
+ +
139  ship->LaunchProbe();
+
140 
+ +
142  ship->ToggleGear();
+
143 
+ + +
146 
+
147  if (drop_state < 0) {
+
148  ship->DropOrbit();
+
149  return;
+
150  }
+
151 
+
152  if (drop_state > 0) {
+
153  ship->MakeOrbit();
+
154  return;
+
155  }
+
156 }
+
157 
+
158 // +--------------------------------------------------------------------+
+
159 
+
160 void
+ +
162 {
+
163  navpt = 0;
+
164  distance = 0;
+
165 
+
166  // runway takeoff:
+
167  if (takeoff) {
+
168  obj_w = ship->Location() + ship->Heading() * 10e3;
+
169  obj_w.y = ship->Location().y + 2e3;
+
170 
+
171  // transform into camera coords:
+ +
173  ship->SetDirectorInfo(Game::GetText("ai.takeoff"));
+
174  return;
+
175  }
+
176 
+
177  // PART I: Find next NavPoint:
+
178  if (ship->GetNavSystem())
+ +
180 
+
181  complete = !navpt;
+
182  if (complete) return;
+
183 
+
184  // PART II: Compute Objective from NavPoint:
+
185  Point npt = navpt->Location();
+
186  Sim* sim = Sim::GetSim();
+
187  SimRegion* self_rgn = ship->GetRegion();
+
188  SimRegion* nav_rgn = navpt->Region();
+
189 
+
190  if (self_rgn && !nav_rgn) {
+
191  nav_rgn = self_rgn;
+
192  navpt->SetRegion(nav_rgn);
+
193  }
+
194 
+
195  if (self_rgn == nav_rgn) {
+
196  if (farcaster) {
+
197  if (farcaster->GetShip()->GetRegion() != self_rgn)
+ +
199 
+
200  obj_w = farcaster->EndPoint();
+
201  }
+
202 
+
203  else {
+
204  obj_w = npt.OtherHand();
+
205  }
+
206 
+
207  // distance from self to navpt:
+
208  distance = Point(obj_w - self->Location()).length();
+
209 
+
210  // transform into camera coords:
+ +
212 
+
213  if (!ship->IsStarship())
+ +
215 
+
216  if (farcaster && distance < 1000)
+
217  farcaster = 0;
+
218  }
+
219 
+
220  // PART III: Deal with orbital transitions:
+
221  else if (ship->IsDropship()) {
+
222  if (nav_rgn->GetOrbitalRegion()->Primary() ==
+
223  self_rgn->GetOrbitalRegion()->Primary()) {
+
224 
+
225  Point npt = nav_rgn->Location() - self_rgn->Location();
+
226  obj_w = npt.OtherHand();
+
227 
+
228  // distance from self to navpt:
+
229  distance = Point(obj_w - ship->Location()).length();
+
230 
+
231  // transform into camera coords:
+ +
233 
+
234  if (nav_rgn->IsAirSpace()) {
+
235  drop_state = -1;
+
236  }
+
237  else if (nav_rgn->IsOrbital()) {
+
238  drop_state = 1;
+
239  }
+
240  }
+
241 
+
242  // PART IIIa: Deal with farcaster jumps:
+
243  else if (nav_rgn->IsOrbital() && self_rgn->IsOrbital()) {
+
244  ListIter<Ship> s = self_rgn->Ships();
+
245  while (++s && !farcaster) {
+
246  if (s->GetFarcaster()) {
+
247  const Ship* dest = s->GetFarcaster()->GetDest();
+
248  if (dest && dest->GetRegion() == nav_rgn) {
+
249  farcaster = s->GetFarcaster();
+
250  }
+
251  }
+
252  }
+
253 
+
254  if (farcaster) {
+
255  Point apt = farcaster->ApproachPoint(0);
+
256  Point npt = farcaster->StartPoint();
+
257  double r1 = (ship->Location() - npt).length();
+
258 
+
259  if (r1 > 50e3) {
+
260  obj_w = apt;
+
261  distance = r1;
+ +
263  }
+
264 
+
265  else {
+
266  double r2 = (ship->Location() - apt).length();
+
267  double r3 = (npt - apt).length();
+
268 
+
269  if (r1+r2 < 1.2*r3) {
+
270  obj_w = npt;
+
271  distance = r1;
+ +
273  }
+
274  else {
+
275  obj_w = apt;
+
276  distance = r2;
+ +
278  }
+
279  }
+
280  }
+
281  }
+
282  }
+
283 
+
284  // PART IV: Deal with quantum jumps:
+
285  else if (ship->IsStarship()) {
+
286  quantum_state = 1;
+
287 
+
288  Point npt = nav_rgn->Location() + navpt->Location();
+
289  npt -= self_rgn->Location();
+
290  obj_w = npt.OtherHand();
+
291 
+
292  // distance from self to navpt:
+
293  distance = Point(obj_w - ship->Location()).length();
+
294 
+
295  // transform into camera coords:
+ +
297  }
+
298 }
+
299 
+
300 // +--------------------------------------------------------------------+
+
301 
+
302 void
+ +
304 {
+
305  accumulator.Clear();
+
306  magnitude = 0;
+
307  brakes = 0;
+
308  hold = false;
+
309 
+
310  if (navpt) {
+
311  if (navpt->Status() == Instruction::COMPLETE && navpt->HoldTime() > 0) {
+
312  ship->SetDirectorInfo(Game::GetText("ai.auto-hold"));
+
313  hold = true;
+
314  }
+
315  else {
+
316  ship->SetDirectorInfo(Game::GetText("ai.auto-nav"));
+
317  }
+
318  }
+
319  else {
+
320  ship->SetDirectorInfo(Game::GetText("ai.auto-stop"));
+
321  }
+
322 
+ + +
325 
+
326  if (!hold)
+ +
328 
+
329  HelmControl();
+
330  ThrottleControl();
+
331 }
+
332 
+
333 // +--------------------------------------------------------------------+
+
334 
+
335 void
+ +
337 {
+
338  // ----------------------------------------------------------
+
339  // STARSHIP HELM MODE
+
340  // ----------------------------------------------------------
+
341 
+
342  if (ship->IsStarship()) {
+ + +
345 
+
346  if (accumulator.pitch > 45*DEGREES)
+ +
348 
+
349  else if (accumulator.pitch < -45*DEGREES)
+
350  ship->SetHelmPitch(-45*DEGREES);
+
351 
+
352  else
+ +
354  }
+
355 
+
356  // ----------------------------------------------------------
+
357  // FIGHTER FLCS AUTO MODE
+
358  // ----------------------------------------------------------
+
359 
+
360  else {
+ +
362 
+
363  // are we being asked to flee?
+
364  if (fabs(accumulator.yaw) == 1.0 && accumulator.pitch == 0.0) {
+
365  accumulator.pitch = -0.7f;
+
366  accumulator.yaw *= 0.25f;
+
367  }
+
368 
+
369  self->ApplyRoll((float) (accumulator.yaw * -0.4));
+
370  self->ApplyYaw((float) (accumulator.yaw * 0.2));
+
371 
+
372  if (fabs(accumulator.yaw) > 0.5 && fabs(accumulator.pitch) < 0.1)
+
373  accumulator.pitch -= 0.1f;
+
374 
+
375  if (accumulator.pitch != 0)
+
376  self->ApplyPitch((float) accumulator.pitch);
+
377 
+
378  // if not turning, roll to orient with world coords:
+
379  if (fabs(accumulator.yaw) < 0.1) {
+
380  Point vrt = ((Camera*) &(self->Cam()))->vrt();
+
381  double deflection = vrt.y;
+
382  if (deflection != 0) {
+
383  double theta = asin(deflection/vrt.length());
+
384  self->ApplyRoll(-theta);
+
385  }
+
386  }
+
387 
+
388  if (!ship->IsAirborne() || ship->AltitudeAGL() > 100)
+
389  ship->RaiseGear();
+
390  }
+
391 
+
392  ship->SetTransX(0);
+
393  ship->SetTransY(0);
+
394  ship->SetTransZ(0);
+
395  ship->ExecFLCSFrame();
+
396 }
+
397 
+
398 // +--------------------------------------------------------------------+
+
399 
+
400 void
+ +
402 {
+
403  double ship_speed = ship->Velocity() * ship->Heading();
+
404  bool augmenter = false;
+
405 
+
406  if (hold) {
+
407  throttle = 0;
+
408  brakes = 1;
+
409  }
+
410 
+
411  else if (navpt) {
+
412  double speed = navpt->Speed();
+
413 
+
414  if (speed < 10)
+
415  speed = 250;
+
416 
+
417  throttle = 0;
+
418 
+
419  if (Ship::GetFlightModel() > 0) {
+
420  if (ship_speed > speed + 10)
+
421  throttle = old_throttle - 0.25;
+
422 
+
423  else if (ship_speed < speed - 10)
+
424  throttle = old_throttle + 0.25;
+
425 
+
426  else
+ +
428  }
+
429 
+
430  else {
+
431  if (ship_speed > speed+5)
+
432  brakes = 0.25;
+
433 
+
434  else if (ship_speed < speed-5)
+
435  throttle = 50;
+
436  }
+
437  }
+
438  else {
+
439  throttle = 0;
+
440  brakes = 0.25;
+
441  }
+
442 
+
443  if (ship->IsAirborne() && ship->Class() < Ship::LCA) {
+
444  if (ship_speed < 250) {
+
445  throttle = 100;
+
446  brakes = 0;
+
447 
+
448  if (ship_speed < 200)
+
449  augmenter = true;
+
450  }
+
451 
+
452  else if (throttle < 20) {
+
453  throttle = 20;
+
454  }
+
455  }
+
456 
+ + +
459  ship->SetAugmenter(augmenter);
+
460 
+
461  if (ship_speed > 1 && brakes > 0)
+ +
463 }
+
464 
+
465 // +--------------------------------------------------------------------+
+
466 
+
467 Steer
+ +
469 {
+
470  if (!ship)
+
471  return Steer();
+
472 
+
473  if (takeoff)
+
474  return Seek(objective);
+
475 
+
476  if (navpt) {
+
477  if (quantum_state == 1) {
+ +
479 
+
480  if (q) {
+ + +
483  q->Engage();
+
484  }
+
485 
+
486  else if (q->ActiveState() == QuantumDrive::ACTIVE_POSTWARP) {
+
487  quantum_state = 0;
+
488  }
+
489  }
+
490  }
+
491 
+
492  if (distance < 2 * self->Radius()) {
+ +
494 
+
495  return Steer();
+
496  }
+
497  else {
+
498  return Seek(objective);
+
499  }
+
500  }
+
501 
+
502  return Steer();
+
503 }
+
504 
+
505 // +--------------------------------------------------------------------+
+
506 
+
507 void
+ +
509 {
+
510  throttle = 0;
+
511 }
+
512 
+
513 // +--------------------------------------------------------------------+
+
514 
+
515 Point
+
516 NavAI::Transform(const Point& point)
+
517 {
+
518  if (ship && ship->IsStarship())
+
519  return point - self->Location();
+
520 
+
521  return SteerAI::Transform(point);
+
522 }
+
523 
+
524 Steer
+
525 NavAI::Seek(const Point& point)
+
526 {
+
527  // if ship is starship, the point is in relative world coordinates
+
528  // x: distance east(-) / west(+)
+
529  // y: altitude down(-) / up(+)
+
530  // z: distance north(-) / south(+)
+
531 
+
532  if (ship && ship->IsStarship()) {
+
533  Steer result;
+
534 
+
535  result.yaw = atan2(point.x, point.z) + PI;
+
536 
+
537  double adjacent = sqrt(point.x * point.x + point.z * point.z);
+
538  if (fabs(point.y) > ship->Radius() && adjacent > ship->Radius())
+
539  result.pitch = atan(point.y / adjacent);
+
540 
+
541  if (_isnan(result.yaw))
+
542  result.yaw = 0;
+
543 
+
544  if (_isnan(result.pitch))
+
545  result.pitch = 0;
+
546 
+
547  return result;
+
548  }
+
549 
+
550  return SteerAI::Seek(point);
+
551 }
+
552 
+
553 Steer
+
554 NavAI::Flee(const Point& point)
+
555 {
+
556  if (ship && ship->IsStarship()) {
+
557  Steer result = Seek(point);
+
558  result.yaw += PI;
+
559  result.pitch *= -1;
+
560  return result;
+
561  }
+
562 
+
563  return SteerAI::Flee(point);
+
564 }
+
565 
+
566 Steer
+
567 NavAI::Avoid(const Point& point, float radius)
+
568 {
+
569  if (ship && ship->IsStarship()) {
+
570  Steer result = Seek(point);
+
571 
+
572  if (point * ship->BeamLine() > 0)
+
573  result.yaw -= PI/2;
+
574  else
+
575  result.yaw += PI/2;
+
576 
+
577  return result;
+
578  }
+
579 
+
580  return SteerAI::Avoid(point, radius);
+
581 }
+
582 
+
583 // +--------------------------------------------------------------------+
+
584 
+
585 Steer
+ +
587 {
+
588  Steer avoid;
+
589 
+
590  terrain_warning = false;
+
591 
+
592  if (!ship || !ship->GetRegion() || !ship->GetRegion()->IsActive() ||
+ +
594  return avoid;
+
595 
+
596  if (ship->IsAirborne() && ship->GetFlightPhase() == Ship::ACTIVE) {
+
597  // too low?
+
598  if (ship->AltitudeAGL() < 1000) {
+
599  terrain_warning = true;
+
600  ship->SetDirectorInfo(Game::GetText("ai.too-low"));
+
601 
+
602  // way too low?
+
603  if (ship->AltitudeAGL() < 750) {
+
604  ship->SetDirectorInfo(Game::GetText("ai.way-too-low"));
+
605  }
+
606 
+
607  // where will we be?
+
608  Point selfpt = ship->Location() + ship->Velocity() + Point(0, 10e3, 0);
+
609 
+
610  // transform into camera coords:
+
611  Point obj = Transform(selfpt);
+
612 
+
613  // pull up!
+
614  avoid = Seek(obj);
+
615  }
+
616  }
+
617 
+
618  return avoid;
+
619 }
+
620 
+
621 
+
622 
+
+
+ + + + -- cgit v1.1