Starshatter_Open
Open source Starshatter engine
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Shot.cpp
Go to the documentation of this file.
1
/* Project Starshatter 4.5
2
Destroyer Studios LLC
3
Copyright (C) 1997-2004. All Rights Reserved.
4
5
SUBSYSTEM: Stars.exe
6
FILE: Shot.cpp
7
AUTHOR: John DiCamillo
8
9
10
OVERVIEW
11
========
12
Laser and Missile class
13
*/
14
15
#include "
MemDebug.h
"
16
#include "
Shot.h
"
17
#include "
Weapon.h
"
18
#include "
DriveSprite.h
"
19
#include "
SeekerAI.h
"
20
#include "
Sim.h
"
21
#include "
Ship.h
"
22
#include "
Trail.h
"
23
#include "
Random.h
"
24
#include "
AudioConfig.h
"
25
#include "
TerrainRegion.h
"
26
#include "
Terrain.h
"
27
28
#include "
Game.h
"
29
#include "
Bolt.h
"
30
#include "
Sprite.h
"
31
#include "
Solid.h
"
32
#include "
Light.h
"
33
#include "
Bitmap.h
"
34
#include "
DataLoader.h
"
35
#include "
Sound.h
"
36
37
// +--------------------------------------------------------------------+
38
39
Shot::Shot
(
const
Point
& pos,
const
Camera
& shot_cam,
WeaponDesign
* dsn,
const
Ship
* ship)
40
: first_frame(true), owner(ship), flash(0), flare(0), trail(0), sound(0), eta(0),
41
charge(1.0f), design(dsn), offset(1.0e5f), altitude_agl(-1.0e6f), hit_target(false)
42
{
43
obj_type
=
SimObject::SIM_SHOT
;
44
type
=
design
->
type
;
45
primary
=
design
->
primary
;
46
beam
=
design
->
beam
;
47
base_damage
=
design
->
damage
;
48
armed
=
false
;
49
50
radius
= 10.0f;
51
52
if
(
primary
||
design
->
decoy_type
|| !
design
->
guided
) {
53
straight
=
true
;
54
armed
=
true
;
55
}
56
57
cam
.
Clone
(shot_cam);
58
59
life
=
design
->
life
;
60
velocity
=
cam
.
vpn
() * (double)
design
->
speed
;
61
62
MoveTo
(pos);
63
64
if
(
beam
)
65
origin
= pos + (shot_cam.
vpn
() * -
design
->
length
);
66
67
switch
(
design
->
graphic_type
) {
68
case
Graphic::BOLT
: {
69
Bolt
* s =
new
(__FILE__,__LINE__)
Bolt
(
design
->
length
,
design
->
width
,
design
->
shot_img
, 1);
70
s->
SetDirection
(
cam
.
vpn
());
71
rep
= s;
72
}
73
break
;
74
75
case
Graphic::SPRITE
: {
76
Sprite
* s = 0;
77
78
if
(
design
->
animation
)
79
s =
new
(__FILE__,__LINE__)
DriveSprite
(
design
->
animation
,
design
->
anim_length
);
80
else
81
s =
new
(__FILE__,__LINE__)
DriveSprite
(
design
->
shot_img
);
82
83
s->
Scale
((
double
)
design
->
scale
);
84
rep
= s;
85
}
86
break
;
87
88
case
Graphic::SOLID
: {
89
Solid
* s =
new
(__FILE__,__LINE__)
Solid
;
90
s->
UseModel
(
design
->
shot_model
);
91
rep
= s;
92
93
radius
=
rep
->
Radius
();
94
}
95
break
;
96
}
97
98
if
(
rep
)
99
rep
->
MoveTo
(pos);
100
101
light
= 0;
102
103
if
(
design
->
light
> 0) {
104
light
=
new
(__FILE__,__LINE__)
Light
(
design
->
light
);
105
light
->
SetColor
(
design
->
light_color
);
106
}
107
108
mass
=
design
->
mass
;
109
drag
=
design
->
drag
;
110
thrust
= 0.0f;
111
112
dr_drg
=
design
->
roll_drag
;
113
dp_drg
=
design
->
pitch_drag
;
114
dy_drg
=
design
->
yaw_drag
;
115
116
SetAngularRates
((
float
)
design
->
roll_rate
, (
float
)
design
->
pitch_rate
, (
float
)
design
->
yaw_rate
);
117
118
if
(
design
->
flash_img
!= 0) {
119
flash
=
new
(__FILE__,__LINE__)
Sprite
(
design
->
flash_img
);
120
flash
->
Scale
((
double
)
design
->
flash_scale
);
121
flash
->
MoveTo
(pos -
cam
.
vpn
() *
design
->
length
);
122
flash
->
SetLuminous
(
true
);
123
}
124
125
if
(
design
->
flare_img
!= 0) {
126
flare
=
new
(__FILE__,__LINE__)
DriveSprite
(
design
->
flare_img
);
127
flare
->
Scale
((
double
)
design
->
flare_scale
);
128
flare
->
MoveTo
(pos);
129
}
130
131
if
(
owner
) {
132
iff_code
= (BYTE)
owner
->
GetIFF
();
133
Observe
((
SimObject
*)
owner
);
134
}
135
136
sprintf_s(
name
,
"Shot(%s)"
,
design
->
name
.
data
());
137
}
138
139
// +--------------------------------------------------------------------+
140
141
Shot::~Shot
()
142
{
143
GRAPHIC_DESTROY
(
flash
);
144
GRAPHIC_DESTROY
(
flare
);
145
GRAPHIC_DESTROY
(
trail
);
146
147
if
(
sound
) {
148
sound
->
Stop
();
149
sound
->
Release
();
150
}
151
}
152
153
// +--------------------------------------------------------------------+
154
155
const
char
*
156
Shot::DesignName
()
const
157
{
158
return
design
->
name
;
159
}
160
161
// +--------------------------------------------------------------------+
162
163
void
164
Shot::SetCharge
(
float
c)
165
{
166
charge
= c;
167
168
// trim beam life to amount of energy available:
169
if
(
beam
)
170
life
=
design
->
life
*
charge
/
design
->
charge
;
171
}
172
173
void
174
Shot::SetFuse
(
double
seconds)
175
{
176
if
(seconds > 0 && !
beam
)
177
life
= seconds;
178
}
179
180
// +--------------------------------------------------------------------+
181
182
void
183
Shot::SeekTarget
(
SimObject
* target,
System
* sub)
184
{
185
if
(
dir
&& !
primary
) {
186
SeekerAI
* seeker = (
SeekerAI
*)
dir
;
187
SimObject
* old_target = seeker->
GetTarget
();
188
189
if
(old_target->
Type
()==
SimObject::SIM_SHIP
) {
190
Ship
* tgt_ship = (
Ship
*) old_target;
191
tgt_ship->
DropThreat
(
this
);
192
}
193
}
194
195
delete
dir
;
196
dir
= 0;
197
198
if
(target) {
199
SeekerAI
* seeker =
new
(__FILE__,__LINE__)
SeekerAI
(
this
);
200
seeker->
SetTarget
(target, sub);
201
seeker->
SetPursuit
(
design
->
guided
);
202
seeker->
SetDelay
(1);
203
204
dir
= seeker;
205
206
if
(!
primary
&& target->
Type
()==
SimObject::SIM_SHIP
) {
207
Ship
* tgt_ship = (
Ship
*) target;
208
tgt_ship->
AddThreat
(
this
);
209
}
210
}
211
}
212
213
bool
214
Shot::IsTracking
(
Ship
* tgt)
const
215
{
216
return
tgt && (
GetTarget
() == tgt);
217
}
218
219
SimObject
*
220
Shot::GetTarget
()
const
221
{
222
if
(
dir
) {
223
SeekerAI
* seeker = (
SeekerAI
*)
dir
;
224
225
if
(seeker->
GetDelay
() <= 0)
226
return
seeker->
GetTarget
();
227
}
228
229
return
0;
230
}
231
232
bool
233
Shot::IsFlak
()
const
234
{
235
return
design
&&
design
->
flak
;
236
}
237
238
// +--------------------------------------------------------------------+
239
240
bool
241
Shot::IsHostileTo
(
const
SimObject
* o)
const
242
{
243
if
(o) {
244
if
(o->
Type
() ==
SIM_SHIP
) {
245
Ship
* s = (
Ship
*) o;
246
247
if
(s->
IsRogue
())
248
return
true
;
249
250
if
(s->
GetIFF
() > 0 && s->
GetIFF
() !=
GetIFF
())
251
return
true
;
252
}
253
254
else
if
(o->
Type
() ==
SIM_SHOT
|| o->
Type
() ==
SIM_DRONE
) {
255
Shot
* s = (
Shot
*) o;
256
257
if
(s->
GetIFF
() > 0 && s->
GetIFF
() !=
GetIFF
())
258
return
true
;
259
}
260
}
261
262
return
false
;
263
}
264
265
// +--------------------------------------------------------------------+
266
267
void
268
Shot::ExecFrame
(
double
seconds)
269
{
270
altitude_agl
= -1.0e6f;
271
272
// add random flickering effect:
273
double
flicker = 0.75 + (double) rand() / 8e4;
274
if
(flicker > 1) flicker = 1;
275
276
if
(
flare
) {
277
flare
->
SetShade
(flicker);
278
}
279
else
if
(
beam
) {
280
Bolt
* blob = (
Bolt
*)
rep
;
281
blob->
SetShade
(flicker);
282
offset
-= (float) (seconds * 10);
283
}
284
285
if
(
Game::Paused
())
286
return
;
287
288
if
(
beam
) {
289
if
(!
first_frame
) {
290
if
(
life
> 0) {
291
life
-= seconds;
292
293
if
(
life
< 0)
294
life
= 0;
295
}
296
}
297
}
298
else
{
299
origin
=
Location
();
300
301
if
(!
first_frame
)
302
Physical::ExecFrame
(seconds);
303
else
304
Physical::ExecFrame
(0);
305
306
double
len =
design
->
length
;
307
if
(len < 50) len = 50;
308
309
if
(!
trail
&&
life
> 0 &&
design
->
life
-
life
> 0.2) {
310
if
(
design
->
trail
.
length
()) {
311
trail
=
new
(__FILE__,__LINE__)
Trail
(
design
->
trail_img
,
design
->
trail_length
);
312
313
if
(
design
->
trail_width
> 0)
314
trail
->
SetWidth
(
design
->
trail_width
);
315
316
if
(
design
->
trail_dim
> 0)
317
trail
->
SetDim
(
design
->
trail_dim
);
318
319
trail
->
AddPoint
(
Location
() +
Heading
() * -100);
320
321
Scene
* scene = 0;
322
323
if
(
rep
)
324
scene =
rep
->
GetScene
();
325
326
if
(scene)
327
scene->
AddGraphic
(
trail
);
328
}
329
}
330
331
if
(
trail
)
332
trail
->
AddPoint
(
Location
());
333
334
if
(!
armed
) {
335
SeekerAI
* seeker = (
SeekerAI
*)
dir
;
336
337
if
(seeker && seeker->
GetDelay
() <= 0)
338
armed
=
true
;
339
}
340
341
// handle submunitions:
342
else
if
(
design
->
det_range
> 0 &&
design
->
det_count
> 0) {
343
if
(
dir
&& !
primary
) {
344
SeekerAI
* seeker = (
SeekerAI
*)
dir
;
345
SimObject
* target = seeker->
GetTarget
();
346
347
if
(target) {
348
double
range =
Point
(
Location
() - target->
Location
()).length();
349
350
if
(range < design->det_range) {
351
life
= 0;
352
353
Sim
* sim =
Sim::GetSim
();
354
WeaponDesign
* child_design =
WeaponDesign::Find
(
design
->
det_child
);
355
356
if
(sim && child_design) {
357
double
spread =
design
->
det_spread
;
358
359
Camera
aim_cam;
360
aim_cam.
Clone
(
Cam
());
361
aim_cam.
LookAt
(target->
Location
());
362
363
for
(
int
i = 0; i <
design
->
det_count
; i++) {
364
Shot
* child = sim->
CreateShot
(
Location
(), aim_cam, child_design,
365
owner
,
owner
->
GetRegion
());
366
367
child->
SetCharge
(child_design->
charge
);
368
369
if
(child_design->
guided
)
370
child->
SeekTarget
(target, seeker->
GetSubTarget
());
371
372
if
(child_design->
beam
)
373
child->
SetBeamPoints
(
Location
(), target->
Location
());
374
375
if
(i) aim_cam.
LookAt
(target->
Location
());
376
aim_cam.
Pitch
(
Random
(-spread, spread));
377
aim_cam.
Yaw
(
Random
(-spread, spread));
378
}
379
}
380
}
381
}
382
}
383
}
384
385
if
(
flash
&& !
first_frame
)
386
GRAPHIC_DESTROY
(
flash
);
387
388
if
(thrust < design->
thrust
)
389
thrust += (float) (seconds * 5.0e3);
390
else
391
thrust =
design
->
thrust
;
392
}
393
394
first_frame
= 0;
395
396
if
(
flare
)
397
flare
->
MoveTo
(
Location
());
398
}
399
400
// +--------------------------------------------------------------------+
401
402
void
403
Shot::Disarm
()
404
{
405
if
(
armed
&& !
primary
) {
406
armed
=
false
;
407
delete
dir
;
408
dir
= 0;
409
}
410
}
411
412
void
413
Shot::Destroy
()
414
{
415
life
= 0;
416
}
417
418
// +--------------------------------------------------------------------+
419
420
void
421
Shot::SetBeamPoints
(
const
Point
& from,
const
Point
& to)
422
{
423
if
(
beam
) {
424
MoveTo
(to);
425
origin
= from;
426
427
if
(
sound
) {
428
sound
->
SetLocation
(from);
429
}
430
431
if
(
rep
) {
432
Bolt
* s = (
Bolt
*)
rep
;
433
s->
SetEndPoints
(from, to);
434
435
double
len =
Point
(to - from).
length
() / 500;
436
s->
SetTextureOffset
(
offset
,
offset
+ len);
437
}
438
}
439
440
if
(
flash
) {
441
flash
->
MoveTo
(
origin
);
442
}
443
}
444
445
// +--------------------------------------------------------------------+
446
447
double
448
Shot::AltitudeMSL
()
const
449
{
450
return
Location
().
y
;
451
}
452
453
double
454
Shot::AltitudeAGL
()
const
455
{
456
if
(
altitude_agl
< -1000) {
457
Shot
* pThis = (
Shot
*)
this
;
// cast-away const
458
Point
loc =
Location
();
459
Terrain
* terrain =
region
->
GetTerrain
();
460
461
if
(terrain)
462
pThis->
altitude_agl
= (float) (loc.
y
- terrain->
Height
(loc.
x
, loc.
z
));
463
464
else
465
pThis->
altitude_agl
= (float) loc.
y
;
466
467
if (!_finite(
altitude_agl
)) {
468
pThis->
altitude_agl
= 0.0f;
469
}
470
}
471
472
return
altitude_agl
;
473
}
474
475
// +--------------------------------------------------------------------+
476
477
void
478
Shot::Initialize
()
479
{
480
}
481
482
// +--------------------------------------------------------------------+
483
484
void
485
Shot::Close
()
486
{
487
}
488
489
// +--------------------------------------------------------------------+
490
491
double
492
Shot::Damage
()
const
493
{
494
double
damage = 0;
495
496
// beam damage based on length:
497
if
(
beam
) {
498
double
fade = 1;
499
500
if
(
design
) {
501
// linear fade with distance:
502
double
len =
Point
(
origin
-
Location
()).
length
();
503
504
if
(len >
design
->
min_range
)
505
fade = (
design
->
length
- len) / (
design
->
length
-
design
->
min_range
);
506
}
507
508
damage =
base_damage
*
charge
* fade *
Game::FrameTime
();
509
}
510
511
// energy wep damage based on time:
512
else
if
(
primary
) {
513
damage =
base_damage
*
charge
*
life
;
514
}
515
516
// missile damage is constant:
517
else
{
518
damage =
base_damage
*
charge
;
519
}
520
521
return
damage;
522
}
523
524
double
525
Shot::Length
()
const
526
{
527
if
(
design
)
528
return
design
->
length
;
529
530
return
500;
531
}
532
533
// +--------------------------------------------------------------------+
534
535
void
536
Shot::Activate
(
Scene
& scene)
537
{
538
SimObject::Activate
(scene);
539
540
if
(
trail
)
541
scene.
AddGraphic
(
trail
);
542
543
if
(
flash
)
544
scene.
AddGraphic
(
flash
);
545
546
if
(
flare
)
547
scene.
AddGraphic
(
flare
);
548
549
if
(
first_frame
) {
550
if
(
design
->
sound_resource
) {
551
sound
=
design
->
sound_resource
->
Duplicate
();
552
553
if
(
sound
) {
554
long
max_vol =
AudioConfig::EfxVolume
();
555
long
volume = -1000;
556
557
if
(volume > max_vol)
558
volume = max_vol;
559
560
if
(
beam
) {
561
sound
->
SetLocation
(
origin
);
562
sound
->
SetVolume
(volume);
563
sound
->
Play
();
564
}
565
else
{
566
sound
->
SetLocation
(
Location
());
567
sound
->
SetVolume
(volume);
568
sound
->
Play
();
569
sound
= 0;
// fire and forget:
570
}
571
}
572
}
573
}
574
}
575
576
// +--------------------------------------------------------------------+
577
578
void
579
Shot::Deactivate
(
Scene
& scene)
580
{
581
SimObject::Deactivate
(scene);
582
583
if
(
trail
)
584
scene.
DelGraphic
(
trail
);
585
586
if
(
flash
)
587
scene.
DelGraphic
(
flash
);
588
589
if
(
flare
)
590
scene.
DelGraphic
(
flare
);
591
}
592
593
// +--------------------------------------------------------------------+
594
595
int
596
Shot::GetIFF
()
const
597
{
598
return
iff_code
;
599
}
600
601
// +--------------------------------------------------------------------+
602
603
Color
604
Shot::MarkerColor
()
const
605
{
606
return
Ship::IFFColor
(
GetIFF
());
607
}
608
609
// +--------------------------------------------------------------------+
610
611
const
char
*
612
Shot::GetObserverName
()
const
613
{
614
return
name
;
615
}
616
617
// +--------------------------------------------------------------------+
618
619
bool
620
Shot::Update
(
SimObject
* obj)
621
{
622
if
(obj == (
SimObject
*)
owner
)
623
owner
= 0;
624
625
return
SimObserver::Update
(obj);
626
}
Stars45
Shot.cpp
Generated on Tue Jun 5 2012 20:47:11 for Starshatter_Open by
1.8.1