Starshatter_Open
Open source Starshatter engine
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
SeekerAI.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: SeekerAI.cpp
7
AUTHOR: John DiCamillo
8
9
10
OVERVIEW
11
========
12
Seeker Missile (low-level) Artificial Intelligence class
13
*/
14
15
#include "
MemDebug.h
"
16
#include "
SeekerAI.h
"
17
#include "
Ship.h
"
18
#include "
Shot.h
"
19
#include "
System.h
"
20
#include "
WeaponDesign.h
"
21
22
#include "
Game.h
"
23
24
// +----------------------------------------------------------------------+
25
26
SeekerAI::SeekerAI
(
SimObject
* s)
27
:
SteerAI
(s), shot((
Shot
*) s), orig_target(0),
28
pursuit(1), delay(0), overshot(false)
29
{
30
ai_type
=
SEEKER
;
31
32
seek_gain
= 25;
33
seek_damp
= 0.55;
34
}
35
36
37
// +--------------------------------------------------------------------+
38
39
SeekerAI::~SeekerAI
()
40
{
41
if
(
shot
) {
42
if
(
shot
->
Owner
())
43
((
Ship
*)
shot
->
Owner
())->SetMissileEta(
shot
->
Identity
(), 0);
44
}
45
}
46
47
// +--------------------------------------------------------------------+
48
49
void
50
SeekerAI::ExecFrame
(
double
seconds)
51
{
52
// setup:
53
FindObjective
();
54
55
// adaptive behavior:
56
Navigator
();
57
}
58
59
// +--------------------------------------------------------------------+
60
61
void
62
SeekerAI::Navigator
()
63
{
64
if
(
delay
> 0) {
65
delay
-=
Game::FrameTime
();
66
}
67
else
{
68
Steer
s =
SeekTarget
();
69
self
->ApplyYaw((
float
) s.
yaw
);
70
self
->ApplyPitch((
float
) s.
pitch
);
71
}
72
}
73
74
void
75
SeekerAI::SetTarget
(
SimObject
* targ,
System
* sub)
76
{
77
if
(!
orig_target
&& targ && targ->
Type
() ==
SimObject::SIM_SHIP
) {
78
orig_target
= (
Ship
*) targ;
79
Observe
(
orig_target
);
80
}
81
82
SteerAI::SetTarget
(targ, sub);
83
84
if
(!
target
) {
85
shot
->
SetEta
(0);
86
87
if
(
shot
->
Owner
())
88
((
Ship
*)
shot
->
Owner
())->SetMissileEta(
shot
->
Identity
(), 0);
89
}
90
}
91
92
void
93
SeekerAI::FindObjective
()
94
{
95
if
(!
shot
|| !
target
)
return
;
96
97
if
(
target
->
Life
() == 0) {
98
if
(
target
!=
orig_target
)
99
SetTarget
(
orig_target
,0);
100
else
101
SetTarget
(0,0);
102
103
return
;
104
}
105
106
Point
tloc =
target
->
Location
();
107
tloc =
Transform
(tloc);
108
109
// seeker head limit of 45 degrees:
110
if
(tloc.
z
< 0 || tloc.
z
< fabs(tloc.
x
) || tloc.
z
< fabs(tloc.
y
)) {
111
overshot
=
true
;
112
SetTarget
(0,0);
113
return
;
114
}
115
116
// distance from self to target:
117
distance
=
Point
(
target
->
Location
() -
self
->Location()).length();
118
119
// are we being spoofed?
120
CheckDecoys
(
distance
);
121
122
Point
cv =
ClosingVelocity
();
123
124
// time to reach target:
125
double
time =
distance
/ cv.
length
();
126
double
predict = time;
127
if
(predict > 15)
128
predict = 15;
129
130
// pure pursuit:
131
if
(
pursuit
== 1 || time < 0.1) {
132
obj_w
=
target
->
Location
();
133
}
134
135
// lead pursuit:
136
else
{
137
// where the target will be when we reach it:
138
Point
run_vec =
target
->
Velocity
();
139
obj_w
=
target
->
Location
() + (run_vec * predict);
140
}
141
142
// subsystem offset:
143
if
(
subtarget
) {
144
Point
offset =
target
->
Location
() -
subtarget
->
MountLocation
();
145
obj_w
-= offset;
146
}
147
else
if
(
target
->
Type
() ==
SimObject::SIM_SHIP
) {
148
Ship
* tgt_ship = (
Ship
*)
target
;
149
150
if
(tgt_ship->
IsGroundUnit
())
151
obj_w
+=
Point
(0,150,0);
152
}
153
154
155
distance
=
Point
(
obj_w
-
self
->
Location
()).length();
156
time =
distance
/ cv.
length
();
157
158
// where we will be when the target gets there:
159
if
(predict > 0.1 && predict < 15) {
160
Point
self_dest =
self
->Location() + cv * predict;
161
Point
err
=
obj_w
- self_dest;
162
163
obj_w
+=
err
;
164
}
165
166
// transform into camera coords:
167
objective
=
Transform
(
obj_w
);
168
objective
.
Normalize
();
169
170
shot
->
SetEta
((
int
) time);
171
172
if
(
shot
->
Owner
())
173
((
Ship
*)
shot
->
Owner
())->SetMissileEta(
shot
->
Identity
(), (int) time);
174
}
175
176
// +--------------------------------------------------------------------+
177
178
void
179
SeekerAI::CheckDecoys
(
double
target_distance)
180
{
181
// if the assigned target has the burner lit,
182
// ignore the decoys:
183
if
(
orig_target
&&
orig_target
->
Augmenter
()) {
184
SetTarget
(
orig_target
);
185
return
;
186
}
187
188
if
(
target
&&
189
target
==
orig_target
&&
190
orig_target
->
GetActiveDecoys
().
size
()) {
191
192
ListIter<Shot>
decoy =
orig_target
->
GetActiveDecoys
();
193
194
while
(++decoy) {
195
double
decoy_distance =
Point
(decoy->
Location
() -
self
->Location()).length();
196
197
if
(decoy_distance < target_distance) {
198
if
(rand() < 1600) {
199
SetTarget
(decoy.
value
(), 0);
200
return
;
201
}
202
}
203
}
204
}
205
}
206
207
// +--------------------------------------------------------------------+
208
209
bool
210
SeekerAI::Overshot
()
211
{
212
return
overshot
;
213
}
214
215
// +--------------------------------------------------------------------+
216
217
Steer
218
SeekerAI::AvoidCollision
()
219
{
220
return
Steer
();
221
}
222
223
// +--------------------------------------------------------------------+
224
225
Steer
226
SeekerAI::SeekTarget
()
227
{
228
if
(!
self
|| !
target
||
Overshot
())
229
return
Steer
();
230
231
return
Seek
(
objective
);
232
}
233
234
// +--------------------------------------------------------------------+
235
236
bool
237
SeekerAI::Update
(
SimObject
* obj)
238
{
239
if
(obj ==
target
) {
240
if
(obj->
Type
() ==
SimObject::SIM_SHOT
&&
orig_target
!= 0)
241
target
=
orig_target
;
242
}
243
244
if
(obj ==
orig_target
)
245
orig_target
= 0;
246
247
return
SteerAI::Update
(obj);
248
}
249
250
const
char
*
251
SeekerAI::GetObserverName
()
const
252
{
253
static
char
name[64];
254
sprintf_s(name,
"SeekerAI(%s)"
,
self
->
Name
());
255
return
name;
256
}
257
Stars45
SeekerAI.cpp
Generated on Tue Jun 5 2012 20:47:09 for Starshatter_Open by
1.8.1