/
pilot_ew.c
272 lines (214 loc) · 6.6 KB
/
pilot_ew.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
* See Licensing and Copyright notice in naev.h
*/
/**
* @file pilot_ew.c
*
* @brief Pilot electronic warfare information.
*/
#include "pilot.h"
#include "naev.h"
#include <math.h>
#include "log.h"
#include "space.h"
#include "player.h"
static double sensor_curRange = 0.; /**< Current base sensor range, used to calculate
what is in range and what isn't. */
#define EVASION_SCALE 1.25 /**< Scales the evasion factor to the hide factor. Ensures that ships always have an evasion factor higher than their hide factor. */
#define SENSOR_DEFAULT_RANGE 7500 /**< The default sensor range for all ships. */
/**
* @brief Updates the pilot's static electronic warfare properties.
*
* @param p Pilot to update.
*/
void pilot_ewUpdateStatic( Pilot *p )
{
p->ew_mass = pilot_ewMass( p->solid->mass );
p->ew_heat = pilot_ewHeat( p->heat_T );
p->ew_hide = p->ew_base_hide * p->ew_mass * p->ew_heat;
}
/**
* @brief Updates the pilot's dynamic electronic warfare properties.
*
* @param p Pilot to update.
*/
void pilot_ewUpdateDynamic( Pilot *p )
{
/* Update hide. */
p->ew_heat = pilot_ewHeat( p->heat_T );
p->ew_hide = p->ew_base_hide * p->ew_mass * p->ew_heat;
/* Update evasion. */
p->ew_movement = pilot_ewMovement( VMOD(p->solid->vel) );
p->ew_evasion = p->ew_hide * EVASION_SCALE;
}
/**
* @brief Gets the electronic warfare movement modifier for a given velocity.
*
* @param vmod Velocity to get electronic warfare movement modifier of.
* @return The electronic warfare movement modifier.
*/
double pilot_ewMovement( double vmod )
{
return 1. + vmod / 100.;
}
/**
* @brief Gets the electronic warfare heat modifier for a given temperature.
*
* @param T Temperature of the ship.
* @return The electronic warfare heat modifier.
*/
double pilot_ewHeat( double T )
{
return 1. - 0.001 * (T - CONST_SPACE_STAR_TEMP);
}
/**
* @brief Gets the electronic warfare mass modifier for a given mass.
*
* @param mass Mass to get the electronic warfare mass modifier of.
* @return The electronic warfare mass modifier.
*/
double pilot_ewMass( double mass )
{
return 1. / (.1 + pow( mass, 0.75 ) / 120. );
}
/**
* @brief Updates the system's base sensor range.
*/
void pilot_updateSensorRange (void)
{
/* Adjust sensor range based on system interference. */
/* See: http://www.wolframalpha.com/input/?i=y+%3D+7500+%2F+%28%28x+%2B+200%29+%2F+200%29+from+x%3D0+to+1000 */
sensor_curRange = SENSOR_DEFAULT_RANGE / ((cur_system->interference + 200) / 200.);
/* Speeds up calculations as we compare it against vectors later on
* and we want to avoid actually calculating the sqrt(). */
sensor_curRange = pow2(sensor_curRange);
}
/**
* @brief Returns the default sensor range for the current system.
*
* @return Sensor range.
*/
double pilot_sensorRange( void )
{
return sensor_curRange;
}
/**
* @brief Check to see if a position is in range of the pilot.
*
* @param p Pilot to check to see if position is in their sensor range.
* @param x X position to check.
* @param y Y position to check.
* @return 1 if the position is in range, 0 if it isn't.
*/
int pilot_inRange( const Pilot *p, double x, double y )
{
double d, sense;
/* Get distance. */
d = pow2(x-p->solid->pos.x) + pow2(y-p->solid->pos.y);
sense = sensor_curRange * p->ew_detect;
if (d < sense)
return 1;
return 0;
}
/**
* @brief Check to see if a pilot is in sensor range of another.
*
* @param p Pilot who is trying to check to see if other is in sensor range.
* @param target Target of p to check to see if is in sensor range.
* @return 1 if they are in range, 0 if they aren't and -1 if they are detected fuzzily.
*/
int pilot_inRangePilot( const Pilot *p, const Pilot *target )
{
double d, sense;
/* Special case player or omni-visible. */
if ((pilot_isPlayer(p) && pilot_isFlag(target, PILOT_VISPLAYER)) ||
pilot_isFlag(target, PILOT_VISIBLE))
return 1;
/* Get distance. */
d = vect_dist2( &p->solid->pos, &target->solid->pos );
sense = sensor_curRange * p->ew_detect;
if (d * target->ew_evasion < sense)
return 1;
else if (d * target->ew_hide < sense)
return -1;
return 0;
}
/**
* @brief Check to see if a planet is in sensor range of the pilot.
*
* @param p Pilot who is trying to check to see if the planet is in sensor range.
* @param target Planet to see if is in sensor range.
* @return 1 if they are in range, 0 if they aren't.
*/
int pilot_inRangePlanet( const Pilot *p, int target )
{
double d;
Planet *pnt;
double sense;
/* pilot must exist */
if ( p == NULL )
return 0;
/* Get the planet. */
pnt = cur_system->planets[target];
/* target must not be virtual */
if ( !pnt->real )
return 0;
/* @TODO ew_detect should be squared upon being set. */
sense = sensor_curRange * pow2(p->ew_detect);
/* Get distance. */
d = vect_dist2( &p->solid->pos, &pnt->pos );
if (d * pnt->hide < sense )
return 1;
return 0;
}
/**
* @brief Check to see if a jump point is in sensor range of the pilot.
*
* @param p Pilot who is trying to check to see if the jump point is in sensor range.
* @param target Jump point to see if is in sensor range.
* @return 1 if they are in range, 0 if they aren't.
*/
int pilot_inRangeJump( const Pilot *p, int i )
{
double d;
JumpPoint *jp;
double sense;
double hide;
/* pilot must exist */
if ( p == NULL )
return 0;
/* Get the jump point. */
jp = &cur_system->jumps[i];
/* We don't want exit-only jumps. */
if (jp_isFlag(jp, JP_EXITONLY))
return 0;
/* Handle hidden jumps separately, as they use a special range parameter. */
if (jp_isFlag(jp, JP_HIDDEN))
sense = pow(p->stats.misc_hidden_jump_detect, 2);
else
sense = sensor_curRange * p->ew_jump_detect;
hide = jp->hide;
/* Get distance. */
d = vect_dist2( &p->solid->pos, &jp->pos );
if (d * hide < sense)
return 1;
return 0;
}
/**
* @brief Calculates the weapon lead (1. is 100%, 0. is 0%)..
*
* @param p Pilot tracking.
* @param t Pilot being tracked.
* @param track Track limit of the weapon.
* @return The lead angle of the weapon.
*/
double pilot_ewWeaponTrack( const Pilot *p, const Pilot *t, double track )
{
double limit, lead;
limit = track * p->ew_detect;
if (t->ew_evasion * t->ew_movement < limit)
lead = 1.;
else
lead = MAX( 0., 1. - 0.5*((t->ew_evasion * t->ew_movement)/limit - 1.));
return lead;
}