Starshatter_Open
Open source Starshatter engine
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
StarshipTacticalAI.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: StarshipTacticalAI.cpp
7
AUTHOR: John DiCamillo
8
9
10
OVERVIEW
11
========
12
Starship-specific mid-level (tactical) AI
13
*/
14
15
#include "
MemDebug.h
"
16
#include "
StarshipTacticalAI.h
"
17
#include "
ShipAI.h
"
18
#include "
Ship.h
"
19
#include "
ShipDesign.h
"
20
#include "
Shot.h
"
21
#include "
Element.h
"
22
#include "
Instruction.h
"
23
#include "
RadioMessage.h
"
24
#include "
RadioTraffic.h
"
25
#include "
Contact.h
"
26
#include "
WeaponGroup.h
"
27
#include "
Drive.h
"
28
#include "
QuantumDrive.h
"
29
#include "
Sim.h
"
30
#include "
StarSystem.h
"
31
#include "
Starshatter.h
"
32
#include "
Random.h
"
33
34
#include "
Game.h
"
35
36
const
double
STARSHIP_TACTICAL_DROP_TIME
= 15;
37
38
// +----------------------------------------------------------------------+
39
40
StarshipTacticalAI::StarshipTacticalAI
(
ShipAI
* ai)
41
:
TacticalAI
(ai), drop_time(1.0e9), bugout(false), ai_level(0), initial_integrity(0)
42
{
43
if
(ai && ai->
GetShip
()) {
44
ai_level
= ai->
GetAILevel
();
45
initial_integrity
= ai->
GetShip
()->
Integrity
();
46
}
47
48
switch
(
ai_level
) {
49
default
:
50
case
2:
THREAT_REACTION_TIME
= 500;
break
;
51
case
1:
THREAT_REACTION_TIME
= 1000;
break
;
52
case
0:
THREAT_REACTION_TIME
= 2500;
53
drop_time
=
STARSHIP_TACTICAL_DROP_TIME
+
54
Random
(0,
STARSHIP_TACTICAL_DROP_TIME
);
55
break
;
56
}
57
}
58
59
60
// +--------------------------------------------------------------------+
61
62
StarshipTacticalAI::~StarshipTacticalAI
()
63
{ }
64
65
// +--------------------------------------------------------------------+
66
67
void
68
StarshipTacticalAI::ExecFrame
(
double
seconds)
69
{
70
TacticalAI::ExecFrame
(seconds);
71
72
drop_time
-= seconds;
73
74
if
(
drop_time
<= 0) {
75
drop_time
=
STARSHIP_TACTICAL_DROP_TIME
;
76
77
ship_ai
->
DropTarget
(
STARSHIP_TACTICAL_DROP_TIME
/4);
78
}
79
}
80
81
// +--------------------------------------------------------------------+
82
83
void
84
StarshipTacticalAI::FindThreat
()
85
{
86
// pick the closest contact on Threat Warning System:
87
Ship
* threat_ship = 0;
88
Shot
* threat_missile = 0;
89
Ship
* rumor = 0;
90
double
threat_dist = 1e9;
91
double
CELL_SIZE = 20e3;
92
93
threat_level
= 0;
94
support_level
=
ship
->
AIValue
() / CELL_SIZE;
95
96
ListIter<Contact>
iter =
ship
->
ContactList
();
97
98
while
(++iter) {
99
Contact
* contact = iter.
value
();
100
Ship
* c_ship = contact->
GetShip
();
101
Shot
* c_shot = contact->
GetShot
();
102
103
if
(!c_ship && !c_shot)
104
continue
;
105
106
if
(c_ship && c_ship !=
ship
) {
107
double
basis = max(contact->
Range
(
ship
), CELL_SIZE);
108
double
ai_value = c_ship->
AIValue
() / basis;
109
110
if
(c_ship->
GetIFF
() ==
ship
->
GetIFF
()) {
111
support_level
+= ai_value;
112
}
113
else
if
(
ship
->
GetIFF
() > 0 && c_ship->
GetIFF
() > 0) {
114
threat_level
+= ai_value;
115
}
116
else
if
(c_ship->
GetIFF
() > 1) {
// neutrals should not be afraid of alliance
117
threat_level
+= ai_value;
118
}
119
}
120
121
if
(contact->
Threat
(
ship
) &&
122
(
Game::GameTime
() - contact->
AcquisitionTime
()) >
THREAT_REACTION_TIME
) {
123
124
if
(c_shot) {
125
threat_missile = c_shot;
126
rumor = (
Ship
* ) threat_missile->
Owner
();
127
}
128
else
{
129
double
rng = contact->
Range
(
ship
);
130
131
if
(c_ship &&
132
c_ship->
Class
() !=
Ship::FREIGHTER
&&
133
c_ship->
Class
() !=
Ship::FARCASTER
) {
134
135
136
if
(c_ship->
GetTarget
() ==
ship
) {
137
if
(!threat_ship || c_ship->
Class
() > threat_ship->
Class
()) {
138
threat_ship = c_ship;
139
threat_dist = 0;
140
}
141
}
142
else
if
(rng < threat_dist) {
143
threat_ship = c_ship;
144
threat_dist = rng;
145
}
146
147
CheckBugOut
(c_ship, rng);
148
}
149
}
150
}
151
}
152
153
if
(rumor) {
154
iter.
reset
();
155
156
while
(++iter) {
157
if
(iter->
GetShip
() == rumor) {
158
rumor = 0;
159
ship_ai
->
ClearRumor
();
160
break
;
161
}
162
}
163
}
164
165
ship_ai
->
SetRumor
(rumor);
166
ship_ai
->
SetThreat
(threat_ship);
167
ship_ai
->
SetThreatMissile
(threat_missile);
168
}
169
170
// +--------------------------------------------------------------------+
171
172
void
173
StarshipTacticalAI::FindSupport
()
174
{
175
if
(
threat_level
< 0.01) {
176
ship_ai
->
SetSupport
(0);
177
return
;
178
}
179
180
// pick the biggest friendly contact in the sector:
181
Ship
* support = 0;
182
double
support_dist = 1e9;
183
184
ListIter<Contact>
c_iter =
ship
->
ContactList
();
185
186
while
(++c_iter) {
187
Contact
* contact = c_iter.
value
();
188
if
(contact->
GetShip
() && contact->
GetIFF
(
ship
) ==
ship
->
GetIFF
()) {
189
Ship
* c_ship = contact->
GetShip
();
190
191
if
(c_ship !=
ship
&& c_ship->
Class
() >=
ship
->
Class
()) {
192
if
(!support || c_ship->
Class
() > support->
Class
())
193
support = c_ship;
194
}
195
}
196
}
197
198
ship_ai
->
SetSupport
(support);
199
}
200
201
void
202
StarshipTacticalAI::CheckBugOut
(
Ship
* c_ship,
double
rng)
203
{
204
// see if carrier should bug out...
205
if
(!
ship
|| !c_ship ||
ship
->
Class
() !=
Ship::CARRIER
)
206
return
;
207
208
if
(
bugout
)
209
return
;
210
211
if
(
ship
->
GetElement
() &&
ship
->
GetElement
()->
GetZoneLock
())
212
return
;
213
214
if
(c_ship->
Class
() <
Ship::DESTROYER
|| c_ship->
Class
() >
Ship::STATION
)
215
return
;
216
217
Starshatter
* stars =
Starshatter::GetInstance
();
218
if
(stars && stars->
InCutscene
())
219
return
;
220
221
double
sustained_damage =
initial_integrity
-
ship
->
Integrity
();
222
double
allowable_damage =
ship
->
Design
()->
integrity
* 0.25;
223
224
if
(rng > 50e3 && sustained_damage < allowable_damage)
225
return
;
226
227
// still here? we must need to bug out!
228
229
Sim
* sim =
Sim::GetSim
();
230
SimRegion
* dst = 0;
231
232
List<SimRegion>
& regions = sim->
GetRegions
();
233
234
if
(regions.
size
() > 1) {
235
int
tries = 10;
236
while
(!dst && tries--) {
237
int
n =
RandomIndex
() % regions.
size
();
238
dst = regions[n];
239
240
if
(dst ==
ship
->
GetRegion
() || dst->
IsAirSpace
())
241
dst = 0;
242
}
243
}
244
245
if
(dst) {
246
// bug out!
247
QuantumDrive
* quantum =
ship
->
GetQuantumDrive
();
248
if
(quantum) {
249
quantum->
SetDestination
(dst,
Point
(0,0,0));
250
quantum->
Engage
();
251
}
252
253
// ask highest ranking escort to go with you:
254
Element
* escort = 0;
255
256
ListIter<Element>
iter = sim->
GetElements
();
257
while
(++iter) {
258
Element
* elem = iter.
value
();
259
260
if
(!escort || elem->
GetShipClass
() > escort->
GetShipClass
()) {
261
if
(
ship
->
GetElement
()->
CanCommand
(elem))
262
escort = elem;
263
}
264
}
265
266
if
(escort) {
267
RadioMessage
* msg =
new
(__FILE__,__LINE__)
RadioMessage
(escort,
ship
,
RadioMessage::QUANTUM_TO
);
268
if
(msg) {
269
msg->
SetInfo
(dst->
Name
());
270
RadioTraffic::Transmit
(msg);
271
}
272
}
273
274
bugout
=
true
;
275
}
276
}
Stars45
StarshipTacticalAI.cpp
Generated on Tue Jun 5 2012 20:47:13 for Starshatter_Open by
1.8.1