From b829170121d3657369904ec62d8065606777a9ce Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Oct 2021 18:54:04 +0200 Subject: Removed doxygen generated docs They can be rebuild anytime and are considered a build artifact/binary. --- Doc/doxygen/html/_weapon_8cpp_source.html | 1301 ----------------------------- 1 file changed, 1301 deletions(-) delete mode 100644 Doc/doxygen/html/_weapon_8cpp_source.html (limited to 'Doc/doxygen/html/_weapon_8cpp_source.html') diff --git a/Doc/doxygen/html/_weapon_8cpp_source.html b/Doc/doxygen/html/_weapon_8cpp_source.html deleted file mode 100644 index d5a147c..0000000 --- a/Doc/doxygen/html/_weapon_8cpp_source.html +++ /dev/null @@ -1,1301 +0,0 @@ - - - - - -Starshatter_Open: D:/SRC/StarshatterSVN/Stars45/Weapon.cpp Source File - - - - - - - - - - - - - -
-
- - - - - - -
-
Starshatter_Open -
-
Open source Starshatter engine
-
-
- - - - - -
-
- -
-
-
- -
- - - - -
- -
- -
-
-
Weapon.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: Weapon.cpp
-
7  AUTHOR: John DiCamillo
-
8 
-
9 
-
10  OVERVIEW
-
11  ========
-
12  Weapon class
-
13 */
-
14 
-
15 #include "MemDebug.h"
-
16 #include "Weapon.h"
-
17 #include "Shot.h"
-
18 #include "Drone.h"
-
19 #include "Contact.h"
-
20 #include "Ship.h"
-
21 #include "Sim.h"
-
22 #include "SimEvent.h"
-
23 #include "Random.h"
-
24 
-
25 #include "NetGame.h"
-
26 #include "NetUtil.h"
-
27 
-
28 #include "Game.h"
-
29 #include "Solid.h"
-
30 
-
31 // +----------------------------------------------------------------------+
-
32 
-
33 Weapon::Weapon(WeaponDesign* d, int nmuz, Vec3* muzzles, double az, double el)
-
34 : System(WEAPON, d->type, d->name, d->value,
-
35 d->capacity, d->capacity, d->recharge_rate),
-
36 design(d), group(d->group), ammo(-1), ripple_count(0),
-
37 aim_azimuth((float) az), aim_elevation((float) el),
-
38 old_azimuth(0.0f), old_elevation(0.0f), aim_time(0),
-
39 enabled(true), refire(0.0f),
-
40 mass(d->carry_mass), resist(d->carry_resist),
-
41 guided(d->guided), shot_speed(d->speed),
-
42 active_barrel(0), locked(false), centered(false), firing(false), blocked(false),
-
43 index(0), target(0), subtarget(0), beams(0), orders(MANUAL),
-
44 control(SINGLE_FIRE), sweep(SWEEP_TIGHT), turret(0), turret_base(0)
-
45 {
-
46  ZeroMemory(visible_stores, sizeof(visible_stores));
-
47 
-
48  if (design->primary)
-
49  abrv = Game::GetText("sys.weapon.primary.abrv");
-
50  else
-
51  abrv = Game::GetText("sys.weapon.secondary.abrv");
-
52 
-
53  nbarrels = nmuz;
-
54 
-
55  if (nbarrels > MAX_BARRELS)
- -
57 
-
58  if (nbarrels == 0 && design->nbarrels > 0) {
- -
60 
-
61  for (int i = 0; i < nbarrels; i++)
- -
63 
-
64  ammo = design->ammo * nbarrels;
-
65  }
-
66  else if (nbarrels == 1 && design->nstores > 0) {
- -
68 
-
69  for (int i = 0; i < nbarrels; i++)
-
70  muzzle_pts[i] = rel_pts[i] = (muzzles[0] + design->attachments[i]);
-
71 
-
72  ammo = nbarrels;
-
73  }
-
74  else {
-
75  for (int i = 0; i < nbarrels; i++)
-
76  muzzle_pts[i] = rel_pts[i] = muzzles[i];
-
77 
-
78  ammo = design->ammo * nbarrels;
-
79  }
-
80 
-
81  if (design->syncro)
-
82  active_barrel = -1;
-
83 
-
84  emcon_power[0] = 0;
-
85  emcon_power[1] = 0;
-
86  emcon_power[2] = 100;
-
87 
- - - -
91 
- - - -
95 }
-
96 
-
97 // +----------------------------------------------------------------------+
-
98 
- -
100 : System(w), design(w.design), ammo(-1), ripple_count(0),
-
101 enabled(true), refire(0.0f),
-
102 mass(w.mass), resist(w.resist),
-
103 aim_azimuth(w.aim_azimuth), aim_elevation(w.aim_elevation),
-
104 old_azimuth(0.0f), old_elevation(0.0f), aim_time(0),
-
105 guided(w.guided), shot_speed(w.shot_speed),
-
106 active_barrel(0), locked(false), centered(false), firing(false), blocked(false),
-
107 target(0), subtarget(0), beams(0), orders(MANUAL),
-
108 control(SINGLE_FIRE), sweep(SWEEP_TIGHT), group(w.group),
-
109 aim_az_max(w.aim_az_max), aim_az_min(w.aim_az_min), aim_az_rest(w.aim_az_rest),
-
110 aim_el_max(w.aim_el_max), aim_el_min(w.aim_el_min), aim_el_rest(w.aim_el_rest),
-
111 turret(0), turret_base(0)
-
112 {
-
113  Mount(w);
-
114  ZeroMemory(visible_stores, sizeof(visible_stores));
-
115 
-
116  nbarrels = w.nbarrels;
-
117 
-
118  for (int i = 0; i < nbarrels; i++) {
-
119  muzzle_pts[i] = rel_pts[i] = w.muzzle_pts[i];
-
120  }
-
121 
-
122  ammo = design->ammo * nbarrels;
-
123 
-
124  if (design->syncro)
-
125  active_barrel = -1;
-
126 
-
127  if (design->beam) {
-
128  beams = new(__FILE__,__LINE__) Shot* [nbarrels];
-
129  ZeroMemory(beams, sizeof(Shot*) * nbarrels);
-
130  }
-
131 
-
132  if (aim_az_rest >= 2*PI)
- -
134 
-
135  if (aim_el_rest >= 2*PI)
- -
137 }
-
138 
-
139 // +--------------------------------------------------------------------+
-
140 
- -
142 {
-
143  if (beams) {
-
144  for (int i = 0; i < nbarrels; i++) {
-
145  if (beams[i]) {
-
146  Ignore(beams[i]);
-
147  delete beams[i];
-
148  beams[i] = 0;
-
149  }
-
150  }
-
151 
-
152  delete [] beams;
-
153  }
-
154 
- - -
157 
-
158  for (int i = 0; i < MAX_BARRELS; i++)
- -
160 }
-
161 
-
162 // +--------------------------------------------------------------------+
-
163 
-
164 bool
- -
166 {
-
167  return design->primary;
-
168 }
-
169 
-
170 bool
- -
172 {
-
173  return design->drone;
-
174 }
-
175 
-
176 bool
- -
178 {
-
179  return design->decoy_type != 0;
-
180 }
-
181 
-
182 bool
- -
184 {
-
185  return design->probe != 0;
-
186 }
-
187 
-
188 bool
- -
190 {
-
191  return !design->primary;
-
192 }
-
193 
-
194 bool
- -
196 {
-
197  return design->beam;
-
198 }
-
199 
-
200 // +--------------------------------------------------------------------+
-
201 
-
202 Shot*
- -
204 {
-
205  if (beams && i >= 0 && i < nbarrels)
-
206  return beams[i];
-
207 
-
208  return 0;
-
209 }
-
210 
-
211 // +--------------------------------------------------------------------+
-
212 
-
213 void
- -
215 {
-
216  ship = s;
-
217 
-
218  if (design->turret_model) {
-
219  Solid* t = new(__FILE__,__LINE__) Solid;
- -
221  turret = t;
-
222  }
-
223 
-
224  if (design->turret_base_model) {
-
225  Solid* t = new(__FILE__,__LINE__) Solid;
- -
227  turret_base = t;
-
228  }
-
229 
-
230  if (!design->primary &&
- -
232  ammo == nbarrels &&
-
233  design->shot_model != 0)
-
234  {
-
235  for (int i = 0; i < nbarrels; i++) {
-
236  Solid* s = new(__FILE__,__LINE__) Solid;
- -
238 
-
239  visible_stores[i] = s;
-
240  }
-
241  }
-
242 }
-
243 
-
244 Solid*
- -
246 {
-
247  return turret;
-
248 }
-
249 
-
250 Solid*
- -
252 {
-
253  return turret_base;
-
254 }
-
255 
-
256 Solid*
- -
258 {
-
259  if (i >= 0 && i < MAX_BARRELS)
-
260  return visible_stores[i];
-
261 
-
262  return 0;
-
263 }
-
264 
-
265 void
- -
267 {
-
268  if (a >= 0) {
-
269  if (active_barrel >= 0 && design->visible_stores) {
-
270  while (a < ammo) {
-
271  if (active_barrel >= nbarrels)
-
272  active_barrel = 0;
-
273 
- -
275  GRAPHIC_DESTROY(visible_stores[active_barrel]);
-
276  active_barrel++;
-
277  ammo--;
-
278  }
-
279  }
-
280  }
-
281 
-
282  ammo = a;
-
283  }
-
284 }
-
285 
-
286 // +--------------------------------------------------------------------+
-
287 
-
288 void
-
289 Weapon::ExecFrame(double seconds)
-
290 {
-
291  System::ExecFrame(seconds);
-
292 
-
293  if (refire > 0)
-
294  refire -= (float) seconds;
-
295 
-
296  locked = false;
-
297  centered = false;
-
298 
-
299  if (!ship)
-
300  return;
-
301 
-
302  if (orders == POINT_DEFENSE && enabled)
-
303  SelectTarget();
-
304 
-
305  if (beams && !target) {
-
306  for (int i = 0; i < nbarrels; i++) {
-
307  if (beams[i]) {
-
308  // aim beam straight:
-
309  Aim();
-
310  SetBeamPoints(false);
-
311  return;
-
312  }
-
313  }
-
314  }
-
315 
-
316  if (design->self_aiming) {
- -
318  }
-
319  else if (turret) {
-
320  ZeroAim();
-
321  }
-
322 
-
323  if (ship->CheckFire())
-
324  return;
-
325 
-
326  // aim beam at target:
-
327  bool aim_beams = false;
-
328 
-
329  if (beams) {
-
330  for (int i = 0; i < nbarrels; i++) {
-
331  if (beams[i]) {
-
332  aim_beams = true;
-
333  SetBeamPoints(true);
-
334  break;
-
335  }
-
336  }
-
337  }
-
338 
-
339  if (!aim_beams) {
-
340  if (ripple_count > 0) {
-
341  if (Fire())
-
342  ripple_count--;
-
343  }
-
344 
-
345  else if (locked && !blocked) {
-
346  if (!ship->IsHostileTo(target))
-
347  return;
-
348 
-
349  if (orders == AUTO && centered) {
-
350  if (energy >= design->charge &&
-
351  (ammo < 0 || target && target->Integrity() >= 1) &&
- -
353  Fire();
-
354  }
-
355 
-
356  else if (orders == POINT_DEFENSE) {
-
357  if (energy >= design->min_charge &&
-
358  (ammo < 0 || target && target->Integrity() >= 1) &&
- -
360  Fire();
-
361  }
-
362  }
-
363  }
-
364 }
-
365 
-
366 // +----------------------------------------------------------------------+
-
367 
-
368 void
-
369 Weapon::Distribute(double delivered_energy, double seconds)
-
370 {
-
371  if (UsesWatts()) {
-
372  if (seconds < 0.01)
-
373  seconds = 0.01;
-
374 
-
375  // convert Joules to Watts:
-
376  energy = (float) (delivered_energy/seconds);
-
377  }
-
378 
-
379  else if (!Game::Paused()) {
-
380  energy += (float) (delivered_energy * 1.25);
-
381 
-
382  if (energy > capacity)
-
383  energy = capacity;
-
384 
-
385  else if (energy < 0)
-
386  energy = 0.0f;
-
387  }
-
388 }
-
389 
-
390 
-
391 // +--------------------------------------------------------------------+
-
392 
-
393 bool
- -
395 {
-
396  if (obj == target) {
-
397  target = 0;
-
398  }
-
399 
-
400  else if (beams) {
-
401  for (int i = 0; i < nbarrels; i++)
-
402  if (obj == beams[i])
-
403  beams[i] = 0;
-
404  }
-
405 
-
406  return SimObserver::Update(obj);
-
407 }
-
408 
-
409 const char*
- -
411 {
-
412  static char name[256];
-
413  sprintf_s(name, "Weapon %s", design->name.data());
-
414  return name;
-
415 }
-
416 
-
417 // +--------------------------------------------------------------------+
-
418 
-
419 void
- -
421 {
-
422  if (o >= MANUAL && o <= POINT_DEFENSE)
-
423  orders = o;
-
424 }
-
425 
-
426 void
- -
428 {
-
429  if (m >= SINGLE_FIRE && m <= SALVO_FIRE)
-
430  control = m;
-
431 }
-
432 
-
433 void
- -
435 {
-
436  if (s >= SWEEP_NONE && s <= SWEEP_WIDE)
-
437  sweep = s;
-
438 }
-
439 
-
440 // +--------------------------------------------------------------------+
-
441 
-
442 bool
-
443 Weapon::CanTarget(DWORD classification) const
-
444 {
-
445  return (design->target_type & classification) ? true : false;
-
446 }
-
447 
-
448 // +--------------------------------------------------------------------+
-
449 
-
450 void
- -
452 {
-
453  // check self targeting:
-
454  if (targ == (SimObject*) ship)
-
455  return;
-
456 
-
457  // check target class filter:
-
458  if (targ) {
-
459  switch (targ->Type()) {
-
460  case SimObject::SIM_SHIP: {
-
461  Ship* tgt_ship = (Ship*) targ;
-
462 
-
463  if ((tgt_ship->Class() & design->target_type) == 0)
-
464  return;
-
465  }
-
466  break;
-
467 
-
468  case SimObject::SIM_SHOT:
-
469  return;
-
470 
-
471  case SimObject::SIM_DRONE: {
-
472  if ((design->target_type & Ship::DRONE) == 0)
-
473  return;
-
474  }
-
475  break;
-
476 
-
477  default:
-
478  return;
-
479  }
-
480  }
-
481 
-
482  // if ok, target this object:
-
483  if (target != targ) {
-
484  target = targ;
-
485 
-
486  if (target)
-
487  Observe(target);
-
488  }
-
489 
-
490  subtarget = sub;
-
491 }
-
492 
-
493 // +--------------------------------------------------------------------+
-
494 
-
495 void
- -
497 {
-
498  bool select_locked = false;
-
499  SimObject* targ = 0;
-
500  double dist = 1e9;
-
501  double az = 0;
-
502  double el = 0;
-
503 
-
504  if (ammo && enabled && (availability > crit_level)) {
-
505  ZeroAim();
-
506 
-
507  ListIter<Contact> contact = ship->ContactList();
-
508 
-
509  // lock onto any threatening shots first (if we can):
-
510  if (design->target_type & Ship::DRONE) {
-
511  while (++contact) {
-
512  Shot* c_shot = contact->GetShot();
-
513 
-
514  if (c_shot && contact->Threat(ship)) {
-
515 
-
516  // distance from self to target:
-
517  double distance = Point(c_shot->Location() - muzzle_pts[0]).length();
-
518 
-
519  if (distance > design->min_range &&
-
520  distance < design->max_range &&
-
521  distance < dist) {
-
522  // check aim basket:
-
523  select_locked = CanLockPoint(c_shot->Location(), az, el);
-
524 
-
525  if (select_locked) {
-
526  targ = c_shot;
-
527  dist = distance;
-
528  }
-
529  }
-
530  }
-
531  }
-
532  }
-
533 
-
534  // lock onto a threatening ship only if it is (much) closer:
-
535  dist *= 0.2;
-
536  contact.reset();
-
537  while (++contact) {
-
538  Ship* c_ship = contact->GetShip();
-
539 
-
540  if (!c_ship) continue;
-
541 
-
542  // can we lock onto this target?
-
543  if ((c_ship->IsRogue() || c_ship->GetIFF() > 0 && c_ship->GetIFF() != ship->GetIFF()) &&
-
544  (c_ship->Class() & design->target_type) &&
-
545  c_ship->Weapons().size() > 0) {
-
546  // distance from self to target:
-
547  double distance = Point(c_ship->Location() - muzzle_pts[0]).length();
-
548 
-
549  if (distance < design->max_range && distance < dist) {
-
550  // check aim basket:
-
551  select_locked = CanLockPoint(c_ship->Location(), az, el);
-
552 
-
553  if (select_locked) {
-
554  targ = c_ship;
-
555  dist = distance;
-
556  }
-
557  }
-
558  }
-
559  }
-
560  }
-
561 
-
562  if (!ammo || !enabled) {
-
563  SetTarget(0,0);
-
564  locked = false;
-
565  }
-
566 
-
567  else {
-
568  SetTarget(targ, 0);
-
569  }
-
570 }
-
571 
-
572 // +--------------------------------------------------------------------+
-
573 
-
574 int
- -
576 {
-
577  if (ammo && enabled && (availability > crit_level)) {
-
578  firing = 0;
-
579  Aim();
-
580  }
-
581  else if (turret) {
-
582  ZeroAim();
-
583  }
-
584 
-
585  return locked;
-
586 }
-
587 
-
588 // +--------------------------------------------------------------------+
-
589 
-
590 Shot*
- -
592 {
-
593  if (Game::Paused())
-
594  return 0;
-
595 
-
596  if (ship && ship->CheckFire())
-
597  return 0;
-
598 
-
599  if (ship->IsStarship() && target && !centered)
-
600  return 0;
-
601 
- -
603  return 0;
-
604 
-
605  Shot* shot = 0;
-
606 
-
607  if (ammo && enabled &&
-
608  (refire <= 0) && (energy > design->min_charge) &&
-
609  (availability > crit_level)) {
-
610 
- -
612 
-
613  NetGame* net_game = NetGame::GetInstance();
-
614  bool net_client = net_game ? net_game->IsClient() : false;
-
615 
-
616  // all barrels
-
617  if (active_barrel < 0) {
-
618  if (net_client || IsPrimary())
- -
620 
-
621  if (!net_game || IsPrimary()) {
-
622  for (int i = 0; i < nbarrels; i++)
-
623  shot = FireBarrel(i);
-
624  }
-
625 
-
626  else if (net_game && net_game->IsServer() && IsMissile()) {
-
627  for (int i = 0; i < nbarrels; i++) {
-
628  shot = FireBarrel(i);
-
629  NetUtil::SendWepRelease(this, shot);
-
630  }
-
631  }
-
632  }
-
633 
-
634  // single barrel
-
635  else {
-
636  if (net_client || IsPrimary())
- -
638 
-
639  if (!net_game || IsPrimary()) {
-
640  shot = FireBarrel(active_barrel++);
-
641  }
-
642 
-
643  else if (net_game && net_game->IsServer() && IsMissile()) {
-
644  shot = FireBarrel(active_barrel++);
-
645  NetUtil::SendWepRelease(this, shot);
-
646  }
-
647 
-
648  if (active_barrel >= nbarrels) {
-
649  active_barrel = 0;
- -
651  }
-
652  }
-
653 
-
654  if (design->ripple_count > 0 && ripple_count <= 0)
- -
656 
-
657  if (status != NOMINAL)
-
658  refire *= 2;
-
659  }
-
660 
-
661  return shot;
-
662 }
-
663 
-
664 // +--------------------------------------------------------------------+
-
665 
-
666 Shot*
- -
668 {
-
669  Shot* shot = 0;
-
670 
-
671  if (!IsPrimary() || Game::Paused())
-
672  return shot;
-
673 
-
674  if (active_barrel < 0 || active_barrel >= nbarrels)
-
675  active_barrel = 0;
-
676 
-
677  target = tgt;
-
678  subtarget = sub;
-
679  aim_time = 0;
-
680 
-
681  for (int i = 0; i < count; i++) {
-
682  shot = FireBarrel(active_barrel++);
-
683 
-
684  if (active_barrel >= nbarrels) {
-
685  active_barrel = 0;
- -
687  }
-
688  }
-
689 
-
690  if (target)
-
691  Observe(target);
-
692 
-
693  return shot;
-
694 }
-
695 
-
696 Shot*
-
697 Weapon::NetFireSecondary(SimObject* tgt, System* sub, DWORD objid)
-
698 {
-
699  Shot* shot = 0;
-
700 
-
701  if (IsPrimary() || Game::Paused())
-
702  return shot;
-
703 
-
704  if (active_barrel < 0 || active_barrel >= nbarrels)
-
705  active_barrel = 0;
-
706 
-
707  target = tgt;
-
708  subtarget = sub;
-
709  aim_time = 0;
-
710 
-
711  shot = FireBarrel(active_barrel++);
-
712 
-
713  if (active_barrel >= nbarrels) {
-
714  active_barrel = 0;
- -
716  }
-
717 
-
718  if (shot)
-
719  shot->SetObjID(objid);
-
720 
-
721  if (target)
-
722  Observe(target);
-
723 
-
724  return shot;
-
725 }
-
726 
-
727 // +--------------------------------------------------------------------+
-
728 
-
729 Shot*
- -
731 {
-
732  const Point& base_vel = ship->Velocity();
-
733  Shot* shot = 0;
-
734  SimRegion* region = ship->GetRegion();
-
735 
-
736  if (!region || n < 0 || n >= nbarrels || Game::Paused())
-
737  return 0;
-
738 
-
739  firing = 1;
-
740  Aim();
-
741 
-
742  Camera rail_cam;
-
743  rail_cam.Clone(aim_cam);
-
744 
-
745  Point shotpos = muzzle_pts[n];
-
746  if (design->length > 0)
-
747  shotpos = shotpos + aim_cam.vpn() * design->length;
-
748 
-
749  // guns may be slewed towards target:
-
750  if (design->primary) {
-
751  shot = CreateShot(shotpos, aim_cam, design, ship);
-
752 
-
753  if (shot) {
-
754  shot->SetVelocity(shot->Velocity() + base_vel);
-
755  }
-
756  }
-
757 
-
758  // missiles always launch in rail direction:
-
759  else {
-
760  // unless they are on a mobile launcher
-
761  if (turret && design->self_aiming) {
-
762  shot = CreateShot(shotpos, aim_cam, design, ship);
-
763  shot->SetVelocity(base_vel);
-
764  }
-
765  else {
-
766  shot = CreateShot(shotpos, rail_cam, design, ship);
-
767  if (shot /* && !turret */) {
-
768  Matrix orient = ship->Cam().Orientation();
-
769  if (aim_azimuth != 0) orient.Yaw(aim_azimuth);
-
770  if (aim_elevation != 0) orient.Pitch(aim_elevation);
-
771 
-
772  Point eject = design->eject * orient;
-
773  shot->SetVelocity(base_vel + eject);
-
774  }
-
775  }
-
776 
-
777  if (shot && visible_stores[n]) {
- -
779  }
-
780  }
-
781 
-
782  if (shot) {
-
783  if (ammo > 0)
-
784  ammo--;
-
785 
-
786  if (guided && target)
-
787  shot->SeekTarget(target, subtarget);
-
788 
-
789  float shot_load;
-
790  if (energy > design->charge)
-
791  shot_load = design->charge;
-
792  else
-
793  shot_load = energy;
-
794 
-
795  energy -= shot_load;
-
796  shot->SetCharge(shot_load * availability);
-
797 
-
798  if (target && design->flak && !design->guided) {
-
799  double speed = shot->Velocity().length();
-
800  double range = (target->Location() - shot->Location()).length();
-
801 
-
802  if (range > design->min_range && range < design->max_range) {
-
803  shot->SetFuse(range / speed);
-
804  }
-
805  }
-
806 
-
807  region->InsertObject(shot);
-
808 
-
809  if (beams) {
-
810  beams[n] = shot;
-
811  Observe(beams[n]);
-
812 
-
813  // aim beam at target:
-
814  SetBeamPoints(true);
-
815  }
-
816 
-
817  if (ship) {
-
818  ShipStats* stats = ShipStats::Find(ship->Name());
-
819 
-
820  if (design->primary)
-
821  stats->AddGunShot();
-
822  else if (design->decoy_type == 0 && design->damage > 0)
-
823  stats->AddMissileShot();
-
824  }
-
825  }
-
826 
-
827  return shot;
-
828 }
-
829 
-
830 Shot*
-
831 Weapon::CreateShot(const Point& loc, const Camera& cam, WeaponDesign* dsn, const Ship* own)
-
832 {
-
833  if (dsn->drone)
-
834  return new(__FILE__,__LINE__) Drone(loc, cam, dsn, own);
-
835 
-
836  else
-
837  return new(__FILE__,__LINE__) Shot(loc, cam, dsn, own);
-
838 }
-
839 
-
840 // +--------------------------------------------------------------------+
-
841 
-
842 void
- -
844 {
-
845  System::Orient(rep);
-
846 
-
847  const Matrix& orientation = rep->Cam().Orientation();
-
848  Point loc = rep->Location();
-
849 
-
850  // align graphics with camera:
-
851  if (turret) {
-
852  if (!design->self_aiming)
-
853  ZeroAim();
-
854 
-
855  const Matrix& aim = aim_cam.Orientation();
-
856 
- -
858  turret->SetOrientation(aim);
-
859 
-
860  if (turret_base) {
-
861  Matrix base = orientation;
-
862 
-
863  if (design->turret_axis == 1) {
-
864  base.Pitch(aim_elevation);
-
865  base.Pitch(old_elevation);
-
866  }
-
867  else {
-
868  base.Yaw(aim_azimuth);
-
869  base.Yaw(old_azimuth);
-
870  }
-
871 
- - -
874  }
-
875 
-
876  for (int i = 0; i < nbarrels; i++) {
-
877  muzzle_pts[i] = (rel_pts[i] * aim) + mount_loc;
-
878 
-
879  if (visible_stores[i]) {
- - -
882  }
-
883  }
-
884  }
-
885  else {
-
886  for (int i = 0; i < nbarrels; i++) {
-
887  muzzle_pts[i] = (rel_pts[i] * orientation) + loc;
-
888 
-
889  if (visible_stores[i]) {
-
890  visible_stores[i]->SetOrientation(orientation);
- -
892  }
-
893  }
-
894  }
-
895 }
-
896 
-
897 // +--------------------------------------------------------------------+
-
898 
-
899 void
- -
901 {
-
902  for (int i = 0; i < nbarrels; i++) {
-
903  if (beams && beams[i]) {
-
904  Point from = muzzle_pts[i];
-
905  Point to;
-
906  double len = design->length;
-
907 
-
908  if (len < 1 || len > 1e7)
-
909  len = design->max_range;
-
910 
-
911  if (len < 1)
-
912  len = 3e5;
-
913 
-
914  else if (len > 1e7)
-
915  len = 1e7;
-
916 
-
917  // always use the aim cam, to enforce slew_rate
-
918  to = from + aim_cam.vpn() * len;
-
919 
-
920  beams[i]->SetBeamPoints(from, to);
-
921  }
-
922  }
-
923 }
-
924 
-
925 // +--------------------------------------------------------------------+
-
926 
-
927 void
- -
929 {
-
930  locked = false;
-
931  centered = false;
-
932 
-
933  FindObjective();
-
934 
-
935  if (target) {
-
936  double az = 0;
-
937  double el = 0;
-
938 
-
939  locked = CanLockPoint(obj_w, az, el, &objective);
-
940 
-
941  double spread_az = design->spread_az;
-
942  double spread_el = design->spread_el;
-
943 
-
944  // beam sweep target:
-
945  if (design->beam) {
-
946  double factor = 0;
-
947  double az_phase = 0;
-
948  double el_phase = 0;
-
949 
-
950  if (target->Type() == SimObject::SIM_SHIP) {
-
951  Ship* s = (Ship*) target;
-
952 
-
953  if (s->IsStarship()) {
-
954  switch (sweep) {
-
955  default:
-
956  case SWEEP_NONE: factor = 0; break;
-
957  case SWEEP_TIGHT: factor = 1; break;
-
958  case SWEEP_WIDE: factor = 2; break;
-
959  }
-
960  }
-
961  }
-
962 
-
963  if (factor > 0) {
-
964  factor *= atan2(target->Radius(), (double) objective.z);
-
965 
-
966  for (int i = 0; i < nbarrels; i++) {
-
967  if (beams && beams[i]) {
-
968  az_phase = sin(beams[i]->Life() * 0.4 * PI);
-
969  el_phase = sin(beams[i]->Life() * 1.0 * PI);
-
970  break;
-
971  }
-
972  }
-
973 
-
974  az += factor * spread_az * az_phase;
-
975  el += factor * spread_el * el_phase * 0.25;
-
976  }
-
977  }
-
978 
-
979  else if (!design->beam) {
-
980  if (spread_az > 0)
-
981  az += Random(-spread_az, spread_az);
-
982 
-
983  if (spread_el > 0)
-
984  el += Random(-spread_el, spread_el);
-
985  }
-
986 
-
987  AimTurret(az, -el);
-
988 
-
989  // check range for guided weapons:
-
990  if (locked && guided) {
-
991  double range = objective.length();
-
992 
-
993  if (range > design->max_track)
-
994  locked = false;
-
995 
-
996  else if (range > design->max_range) {
-
997  if (firing) {
-
998  if (RandomChance(1,4)) // 1 in 4 chance of locking anyway
-
999  locked = false;
-
1000  }
-
1001  else {
-
1002  locked = false;
-
1003  }
-
1004  }
-
1005  }
-
1006 
-
1007  if (locked) {
-
1008  Point tloc = target->Location();
-
1009  tloc = Transform(tloc);
-
1010 
-
1011  if (tloc.z > 1) {
-
1012  az = atan2(fabs(tloc.x), tloc.z);
-
1013  el = atan2(fabs(tloc.y), tloc.z);
-
1014 
-
1015  double firing_cone = 10*DEGREES;
-
1016 
-
1017  if (orders == MANUAL)
-
1018  firing_cone = 30*DEGREES;
-
1019 
-
1020  if (az < firing_cone && el < firing_cone)
-
1021  centered = true;
-
1022  }
-
1023  }
-
1024  }
-
1025  else {
- -
1027  }
-
1028 }
-
1029 
-
1030 void
- -
1032 {
-
1033  ZeroAim();
-
1034 
-
1035  if (!target || !design->self_aiming) {
-
1036  objective = Point();
-
1037  return;
-
1038  }
-
1039 
-
1040  obj_w = target->Location();
-
1041 
-
1042  if (subtarget) {
- -
1044  }
-
1045  else if (target->Type() == SimObject::SIM_SHIP) {
-
1046  Ship* tgt_ship = (Ship*) target;
-
1047 
-
1048  if (tgt_ship->IsGroundUnit())
-
1049  obj_w += Point(0,150,0);
-
1050  }
-
1051 
-
1052  if (!design->beam && shot_speed > 0) {
-
1053  // distance from self to target:
-
1054  double distance = Point(obj_w - muzzle_pts[0]).length();
-
1055 
-
1056  // TRUE shot speed is relative to ship speed:
-
1057  Point eff_shot_vel = ship->Velocity() + aim_cam.vpn() * shot_speed - target->Velocity();
-
1058  double eff_shot_speed = eff_shot_vel.length();
-
1059 
-
1060  // time to reach target:
-
1061  double time = distance / eff_shot_speed;
-
1062 
-
1063  // where the target will be when the shot reaches it:
-
1064  obj_w += (target->Velocity() - ship->Velocity()) * time +
-
1065  target->Acceleration() * 0.25 * time * time;
-
1066  }
-
1067 
-
1068  // transform into camera coords:
- -
1070 }
-
1071 
-
1072 Point
- -
1074 {
-
1075  Point result;
-
1076 
-
1077  Point obj_t = pt - aim_cam.Pos();
-
1078  result.x = obj_t * aim_cam.vrt();
-
1079  result.y = obj_t * aim_cam.vup();
-
1080  result.z = obj_t * aim_cam.vpn();
-
1081 
-
1082  return result;
-
1083 }
-
1084 
-
1085 bool
-
1086 Weapon::CanLockPoint(const Point& test, double& az, double& el, Point* obj)
-
1087 {
-
1088  Point pt = Transform(test);
-
1089  bool locked = true;
-
1090 
-
1091  // first compute az:
-
1092  if (fabs(pt.z) < 0.1) pt.z = 0.1;
-
1093  az = atan(pt.x / pt.z);
-
1094  if (pt.z < 0) az -= PI;
-
1095  if (az < -PI) az += 2*PI;
-
1096 
-
1097  // then, rotate target into az-coords to compute el:
-
1098  Camera tmp;
-
1099  tmp.Clone(aim_cam);
-
1100  aim_cam.Yaw(az);
-
1101  pt = Transform(test);
-
1102  aim_cam.Clone(tmp);
-
1103 
-
1104  if (fabs(pt.z) < 0.1) pt.z = 0.1;
-
1105  el = atan(pt.y / pt.z);
-
1106 
-
1107  if (obj) *obj = pt;
-
1108 
-
1109  // is the target in the basket?
-
1110  // clamp if necessary:
-
1111 
-
1112  if (az > aim_az_max) {
-
1113  az = aim_az_max;
-
1114  locked = false;
-
1115  }
-
1116  else if (az < aim_az_min) {
-
1117  az = aim_az_min;
-
1118  locked = false;
-
1119  }
-
1120 
-
1121  if (el > aim_el_max) {
-
1122  el = aim_el_max;
-
1123  locked = false;
-
1124  }
-
1125  else if (el < aim_el_min) {
-
1126  el = aim_el_min;
-
1127  locked = false;
-
1128  }
-
1129 
-
1130  if (IsDrone() && guided) {
-
1131  double firing_cone = 10*DEGREES;
-
1132 
-
1133  if (orders == MANUAL)
-
1134  firing_cone = 20*DEGREES;
-
1135 
-
1136  if (az < firing_cone && el < firing_cone)
-
1137  locked = true;
-
1138  }
-
1139 
-
1140  return locked;
-
1141 }
-
1142 
-
1143 // +--------------------------------------------------------------------+
-
1144 
-
1145 void
-
1146 Weapon::AimTurret(double az, double el)
-
1147 {
-
1148  double seconds = (Game::GameTime() - aim_time) / 1000.0;
-
1149 
-
1150  // don't let the weapon turn faster than turret slew rate:
-
1151  double max_turn = design->slew_rate * seconds;
-
1152 
-
1153  if (fabs(az-old_azimuth) > max_turn) {
-
1154  if (az > old_azimuth)
-
1155  az = old_azimuth + max_turn;
-
1156  else
-
1157  az = old_azimuth - max_turn;
-
1158  }
-
1159 
-
1160  if (fabs(el-old_elevation) > PI/2 * seconds) {
-
1161  if (el > old_elevation)
-
1162  el = old_elevation + max_turn;
-
1163  else
-
1164  el = old_elevation - max_turn;
-
1165  }
-
1166 
-
1167  aim_cam.Yaw(az);
-
1168  aim_cam.Pitch(el);
-
1169 
-
1170  old_azimuth = (float) az;
-
1171  old_elevation = (float) el;
-
1172 
- -
1174 }
-
1175 
-
1176 void
- -
1178 {
-
1179  aim_cam.Clone(ship->Cam());
-
1180  if (aim_azimuth != 0) aim_cam.Yaw(aim_azimuth);
- -
1182 
- -
1184 }
-
-
- - - - -- cgit v1.1