Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CampaignPlanMovement.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: CampaignPlanMovement.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  CampaignPlanMovement simulates random patrol movements
13  of starship groups between missions.
14 */
15 
16 #include "MemDebug.h"
17 #include "CampaignPlanMovement.h"
18 #include "Campaign.h"
19 #include "Combatant.h"
20 #include "CombatGroup.h"
21 #include "CombatUnit.h"
22 #include "CombatZone.h"
23 #include "Random.h"
24 #include "ShipDesign.h"
25 
26 // +--------------------------------------------------------------------+
27 
28 void
30 {
31  if (campaign && campaign->IsActive()) {
32  if (Campaign::Stardate() - exec_time < 7200)
33  return;
34 
36 
38  while (++iter) {
39  CombatUnit* u = iter.value();
40 
41  if (u->IsStarship() && !u->IsStatic())
42  MoveUnit(u);
43  }
44 
45  all_units.clear();
46 
48  }
49 }
50 
51 // +--------------------------------------------------------------------+
52 
53 void
55 {
56  if (u) {
57  // starship repair:
58  double damage = u->GetSustainedDamage();
59 
60  if (damage > 0 && u->GetDesign()) {
61  int percent = (int) (100 * damage / u->GetDesign()->integrity);
62 
63  if (percent > 50) {
64  u->SetSustainedDamage(0.90 * damage);
65  }
66  }
67 
68  Point loc = u->Location();
69  Point dir = loc;
70  double dist = dir.Normalize();
71 
72  const double MAX_RAD = 320e3;
73  const double MIN_DIST = 150e3;
74 
75  if (dist < MAX_RAD) {
76  double scale = 1 - dist/MAX_RAD;
77 
78  loc += dir * (Random(30e3, 90e3) * scale) + RandomDirection() * 10e3;
79 
80  if (fabs(loc.z) > 20e3)
81  loc.z *= 0.1;
82 
83  u->MoveTo(loc);
84 
85  CombatGroup* g = u->GetCombatGroup();
86  if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) {
87  g->MoveTo(loc);
88 
89  if (g->IntelLevel() > Intel::KNOWN)
91  }
92  }
93 
94  else if (dist > 1.25 * MAX_RAD) {
95  double scale = 1 - dist/MAX_RAD;
96 
97  loc += dir * (Random(80e3, 120e3) * scale) + RandomDirection() * 3e3;
98 
99  if (fabs(loc.z) > 20e3)
100  loc.z *= 0.1;
101 
102  u->MoveTo(loc);
103 
104  CombatGroup* g = u->GetCombatGroup();
105  if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) {
106  g->MoveTo(loc);
107 
108  if (g->IntelLevel() > Intel::KNOWN)
110  }
111  }
112 
113  else {
114  loc += RandomDirection() * 30e3;
115 
116  if (fabs(loc.z) > 20e3)
117  loc.z *= 0.1;
118 
119  u->MoveTo(loc);
120 
121  CombatGroup* g = u->GetCombatGroup();
122  if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) {
123  g->MoveTo(loc);
124 
125  if (g->IntelLevel() > Intel::KNOWN)
127  }
128  }
129 
130  CombatUnit* closest_unit = 0;
131  double closest_dist = 1e6;
132 
134  while (++iter) {
135  CombatUnit* unit = iter.value();
136 
137  if (unit->GetCombatGroup() != u->GetCombatGroup() && unit->GetRegion() == u->GetRegion() && !unit->IsDropship()) {
138  Point delta = loc - unit->Location();
139  dist = delta.Normalize();
140 
141  if (dist < closest_dist) {
142  closest_unit = unit;
143  closest_dist = dist;
144  }
145  }
146  }
147 
148  if (closest_unit && closest_dist < MIN_DIST) {
149  Point delta = loc - closest_unit->Location();
150  dist = delta.Normalize();
151 
152  loc += delta * 1.1 * (MIN_DIST - closest_dist);
153 
154  if (fabs(loc.z) > 20e3)
155  loc.z *= 0.1;
156 
157  u->MoveTo(loc);
158 
159  CombatGroup* g = u->GetCombatGroup();
160  if (g && g->Type() > CombatGroup::FLEET && g->GetFirstUnit() == u) {
161  g->MoveTo(loc);
162 
163  if (g->IntelLevel() > Intel::KNOWN)
165  }
166  }
167  }
168 }