Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sensor.cpp
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 
3 #include "cmd/unit_generic.h"
4 #include "cmd/planet_generic.h"
5 #include "cmd/unit_util.h"
6 #include "cmd/unit_find.h"
7 #include "sensor.h"
8 
9 extern Unit *getTopLevelOwner(); // WTF... located in star_system_generic.cpp
10 
11 namespace
12 {
13 
14 GFXColor RetrColor( const std::string &name, GFXColor def = GFXColor( 1, 1, 1, 1 ) )
15 {
16  vs_config->getColor( name, &def.r );
17  return def;
18 }
19 
20 } // anonymous namespace
21 
22 namespace Radar
23 {
24 
26  : player(player),
27  closeRange(30000.0),
28  useThreatAssessment(false)
29 {
30 }
31 
33 {
34  return player;
35 }
36 
38 {
39  assert(player);
40 
42 }
43 
45 {
46  assert(player);
47 
49 }
50 
52 {
53  assert(player);
54 
56 }
57 
58 float Sensor::GetCloseRange() const
59 {
60  return closeRange;
61 }
62 
63 float Sensor::GetMaxRange() const
64 {
65  assert(player);
66 
68 }
69 
70 float Sensor::GetMaxCone() const
71 {
72  assert(player);
73 
75 }
76 
77 float Sensor::GetLockCone() const
78 {
79  assert(player);
80 
82 }
83 
85 {
86  assert(player);
87 
88  return Track(player, target);
89 }
90 
91 Track Sensor::CreateTrack(Unit *target, const Vector& position) const
92 {
93  assert(player);
94 
95  return Track(player, target, position);
96 }
97 
98 bool Sensor::IsTracking(const Track& track) const
99 {
100  assert(player);
101 
102  return (track.target == player->Target());
103 }
104 
106 {
107  assert(player);
108 
109  return (player->GetNebula() != NULL);
110 }
111 
112 bool Sensor::InRange(const Track& track) const
113 {
114  return (track.GetDistance() <= GetMaxRange());
115 }
116 
117 // FIXME: This is a convoluted way to obtain the radar tracks
118 
120 {
121 public:
123  : sensor(NULL),
124  player(NULL),
125  collection(NULL)
126  {}
127 
128  void init(const Sensor *sensor, Sensor::TrackCollection *collection, Unit *player)
129  {
130  this->sensor = sensor;
131  this->collection = collection;
132  this->player = player;
133  }
134 
135  bool acquire(Unit *target, float distance)
136  {
137  assert(sensor);
138  assert(collection);
139  assert(player);
140  assert(target);
141 
142  static bool draw_significant_blips =
143  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "draw_significant_blips", "true" ) );
144  static bool untarget_out_cone =
145  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "hud", "untarget_beyond_cone", "false" ) );
146  static float minblipsize =
147  XMLSupport::parse_float( vs_config->getVariable( "graphics", "hud", "min_radarblip_size", "0" ) );
148 
149  if (target != player) {
150  const bool isCurrentTarget = (player->Target() == target);
151  double dummy;
152  if (!player->InRange( target, dummy, isCurrentTarget && untarget_out_cone, true, true ))
153  {
154  if (isCurrentTarget)
155  player->Target(NULL);
156  return true;
157  }
158  if (!isCurrentTarget &&
159  !draw_significant_blips &&
160  (getTopLevelOwner() == target->owner) &&
161  (distance > player->GetComputerData().radar.maxrange))
162  return true;
163 
164  // Blips will be sorted later as different radars need to sort them differently
165  if (target->rSize() > minblipsize)
166  {
167  collection->push_back(sensor->CreateTrack(target));
168  }
169  if (target->isPlanet() == PLANETPTR && target->radial_size > 0)
170  {
171  Unit *sub = NULL;
172  for (un_kiter i = target->viewSubUnits(); (sub = *i) != NULL; ++i)
173  {
174  if (target->rSize() > minblipsize)
175  {
176  collection->push_back(sensor->CreateTrack(sub));
177  }
178  }
179  }
180  }
181  return true;
182  }
183 
184 private:
185  const Sensor *sensor;
186  Unit *player;
187  Sensor::TrackCollection *collection;
188 };
189 
190 // FIXME: Scale objects according to distance and ignore those below a given threshold (which improves with better sensors)
192 {
193  assert(player);
194 
195  collection.clear();
196 
197  // Find all units within range
198  static float maxUnitRadius =
199  XMLSupport::parse_float(vs_config->getVariable("graphics", "hud", "radar_search_extra_radius", "1000"));
200  static bool allGravUnits =
201  XMLSupport::parse_bool(vs_config->getVariable("graphics", "hud", "draw_gravitational_objects", "true"));
202 
203  UnitWithinRangeLocator<CollectRadarTracks> unitLocator(GetMaxRange(), maxUnitRadius);
204  unitLocator.action.init(this, &collection, player);
206  {
209  &unitLocator);
210  }
211  if (allGravUnits)
212  {
213  Unit *target = player->Target();
214  Unit *gravUnit;
215  bool foundtarget = false;
217  (gravUnit = *i) != NULL;
218  ++i)
219  {
220  unitLocator.action.acquire(gravUnit, UnitUtil::getDistance(player, gravUnit));
221  if (gravUnit == target)
222  foundtarget = true;
223  }
224  if (target && !foundtarget)
225  unitLocator.action.acquire(target, UnitUtil::getDistance(player, target));
226  }
227  return collection;
228 }
229 
231 {
232  assert(player);
233 
234  if (!UseThreatAssessment())
235  return ThreatLevel::None;
236 
237  if (track.IsExploding())
238  return ThreatLevel::None;
239 
240  if (track.HasWeaponLock())
241  {
242  // I am being targetted by...
243  switch (track.GetType())
244  {
246  return ThreatLevel::High;
247 
249  if (track.GetRelation() == Track::Relation::Enemy)
250  return ThreatLevel::Medium;
251  break;
252 
253  case Track::Type::Ship:
254  if (track.HasTurrets())
255  return ThreatLevel::Medium;
256 
257  if (!track.HasWeapons())
258  {
259  // So what are you going to threaten me with? Exhaustion gas?
260  return ThreatLevel::None;
261  }
262  break;
263 
264  default:
265  break;
266  }
267  return ThreatLevel::Low;
268  }
269  return ThreatLevel::None;
270 }
271 
272 GFXColor Sensor::GetColor(const Track& track) const
273 {
274  assert(player);
275 
276  static GFXColor friendColor = RetrColor("friend", GFXColor(-1, -1, -1, -1));
277  static GFXColor enemyColor = RetrColor("enemy", GFXColor(-1, -1, -1, -1));
278  static GFXColor neutralColor = RetrColor("neutral", GFXColor(-1, -1, -1, -1));
279  static GFXColor baseColor = RetrColor("base", GFXColor( -1, -1, -1, -1 ));
280  static GFXColor planetColor = RetrColor("planet", GFXColor( -1, -1, -1, -1 ));
281  static GFXColor jumpColor = RetrColor("jump", GFXColor( 0, 1, 1, .8 ));
282  static GFXColor navColor = RetrColor("nav", GFXColor( 1, 1, 1, 1 ));
283  static GFXColor starColor = RetrColor("star", GFXColor( 1, 1, 1, 1 ));
284  static GFXColor missileColor = RetrColor("missile", GFXColor( .25, 0, .5, 1 ));
285  static GFXColor cargoColor = RetrColor("cargo", GFXColor( .6, .2, 0, 1 ));
286  static GFXColor noColor = RetrColor("black_and_white", GFXColor( .5, .5, .5 ));
287 
288  Track::Type::Value trackType = track.GetType();
289  ThreatLevel::Value threatLevel = IdentifyThreat(track);
290 
291  if (UseThreatAssessment())
292  {
293  switch (trackType)
294  {
296  return missileColor;
297 
298  default:
299  break;
300  }
301  }
302 
303  if (UseObjectRecognition())
304  {
305  switch (trackType)
306  {
307  case Track::Type::Nebula:
308  case Track::Type::Star:
309  return starColor;
310 
311  case Track::Type::Planet:
313  return planetColor;
314 
315  case Track::Type::Base:
316  if (track.HasLock())
317  return enemyColor;
318  return baseColor;
319 
321  return jumpColor;
322 
323  default:
324  break;
325  }
326  }
327 
328  if (UseFriendFoe())
329  {
330  switch (trackType)
331  {
333  case Track::Type::Ship:
334  {
335  if (track.HasLock())
336  return enemyColor;
337 
338  switch (track.GetRelation())
339  {
341  return friendColor;
342 
344  if (UseThreatAssessment() && (threatLevel == ThreatLevel::None))
345  return neutralColor;
346 
347  return enemyColor;
348 
349  default:
350  return neutralColor;
351  }
352  }
353 
354  case Track::Type::Cargo:
355  return cargoColor;
356 
357  default:
358  break;
359  }
360  }
361  return noColor;
362 }
363 
364 } // namespace Radar