Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
brains.c
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup flight
4 * @brief NPC pilot intelligence (the original BRAINS.C).
5 *
6 * Address range 409760-40b66f. The surviving WINGLEADER module and the Mac
7 * brain symbol run both cover cruise_home through FF_missile_intelligence.
8 */
9#include "wc1.h"
10#include <dos.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <assert.h>
14
15/* The leaked BRAINS.C declares this logic routine locally. The other local
16 * callee declarations below follow that style; their parameter names are
17 * part of the measured compiler context. */
18unsigned int change_mission_type(short obj, enum ShipMissionType missionType);
19
20short nEnemySighting = 0x7fff; /* 0x00465c7c */
21
22/* Linker commons defined here; LINK orders them by identifier hash. */
23struct Shape *pScrambleDetailShape; /* 0x005a86bc */
24short nScrambleCockpitAngle; /* 0x005a86c0 */
26short nFuneralCasketPositionX; /* 0x005a86c8 */
27short nFuneralCasketPosY; /* 0x005a86ca */
28
29/* Function start: 0x409760 */
30void cruise_home(short obj)
31{
32 short range;
33 short objective;
34
35 if (abandoned(obj, 0) != 0)
36 return;
37
38 if ((abShipTurnList[obj] & 7) == 5) {
39 if (nYourWingman == obj &&
40 distance_from_object(obj, 0) > 16000)
41 remove_object(obj);
42
45 else if (normal_speed(obj) != 0)
46 fire_afterburner(obj, 10);
47
48 if (no_goal(obj) != 0)
51
53 &aShipMissionSpotArray[obj])) {
54 if (range < 5000) {
58 }
59 } else if (range < 1500) {
60 objective = abFlightPathList[abShipNavPtIdx[obj]];
61 if (aMissionObjectivesArray[objective].type != 1)
62 flag_objective(objective, 1);
64 }
65 }
66}
67
68/* Function start: 0x4098C0 */
69void fail(short obj)
70{
72}
73
74/* Function start: 0x4098D0 */
75void coming_home(short obj)
76{
77 short objective;
78
79 switch (aeShipTacticArray[obj]) {
80 case TACTIC_NONE:
82 if (aeShipSide[obj] == SIDE_IMPERIAL &&
84 objective = find_objective(1, -1);
87 } else {
89 }
90 break;
91 case TACTIC_CRUISE:
92 cruise_home(obj);
93 break;
95 if (no_goal(obj) != 0)
97 break;
98 default:
99 fail(obj);
100 break;
101 }
102}
103
104/* Function start: 0x4099C0 */
105void run_away(short obj)
106{
107 FixedVector direction;
108
109 if (unactive(asShipWingLeaderArray[obj]) == 0 &&
113 return;
114 }
115 if (aeShipSide[obj] == SIDE_IMPERIAL) {
116 coming_home(obj);
117 return;
118 }
119
120 zero_vector(&direction);
121 direction.y = 0x100;
122 if ((obj & 1) != 0)
123 direction.y = -0x100;
124 point_ship(obj, 0, &direction);
125 if (normal_speed(obj) != 0 &&
126 (RandomBelow(100) < 50 || any_enemy(obj, 16000) != 0))
127 fire_afterburner(obj, 40);
128 else
130 if (distance_from_object(obj, 0) > 16000)
131 remove_object(obj);
132}
133
134/* Function start: 0x409AC0 */
135short check_engage_target(short obj)
136{
137 short newTarget = detect_enemy_tail(obj);
138
139 if (newTarget != -1 && newTarget != acShipTargetTable[obj])
140 acShipTargetTable[obj] = newTarget;
141 else if (target_valid(obj) == 0)
142 select_target(obj);
143 return acShipTargetTable[obj];
144}
145
146/* Function start: 0x409B10 */
147short check_destroy_target(short obj)
148{
149 short destroyTarget = find_ship_index(anShipMissionShips[obj]);
150
151 if (destroyTarget == -1) {
153 } else if (aeObjectClass[destroyTarget] ==
155 gone_ship(anShipMissionShips[obj]) != 0) {
157 } else if (evaluate_damage(obj) > 70 - MaxShort(
158 0, MinShort(4, (short)aiPilotLevel[obj])) * 15) {
159 acShipTargetTable[obj] = destroyTarget;
160 if (aeShipSide[destroyTarget] ==
161 aeShipSide[obj])
162 acShipTargetTable[obj] = -1;
163 } else if (target_valid(obj) != 0 && RandomBelow(100) > 3) {
165 } else {
166 acShipTargetTable[obj] = destroyTarget;
167 }
168 return acShipTargetTable[obj];
169}
170
171/* Function start: 0x409C20 */
172void maneuvering(short obj, short newTarget)
173{
174 acShipTargetTable[obj] = newTarget;
176 perform_maneuver(obj);
177}
178
179/* Function start: 0x409C50 */
180void formation_burst(short obj)
181{
183 if (no_goal(obj) != 0)
184 point_ship(obj, 0, &aShipDestinationsArray[obj]);
185 asShipTotal[obj]++;
186 if (asShipTotal[obj] > 9) {
188 engage(obj, acShipTargetTable[obj],
190 else
191 engage(obj, acShipTargetTable[obj],
193 }
194}
195
196/* Function start: 0x409CE0 */
198{
199 bEngageAllowed = 0;
200}
201
202/* Function start: 0x409CF0 */
203void allow_engage(void)
204{
205 bEngageAllowed = 1;
206 nAutoEngageTimer = -1;
207}
208
209/* Function start: 0x409D10 */
210void try2allow_engage(int pilotLevel)
211{
212 if (pilotLevel <= 4) {
213 allow_engage();
214 return;
215 }
216 if (pilotLevel == 8 || pilotLevel == 11 || pilotLevel == 6) {
217 allow_engage();
218 return;
219 }
220 if (pilotLevel == 5 && RandomBelowOrEqual(100) < 50) {
221 allow_engage();
222 return;
223 }
224 nAutoEngageTimer = -40;
225}
226
227int attacker_in_range(short obj, unsigned short range);
228
229/* Function start: 0x409D60 */
230void imperial_formation(short obj)
231{
232 short leader = asShipWingLeaderArray[obj];
233 short target;
234 FixedVector dest;
235 short closest;
236
237 if (leader == -1)
238 leader = obj;
240 if (attacker_in_range(leader, 12000) != 0) {
241 if (obj == nYourWingman ||
242 nYourWingman == -1) {
243 if (nAutoEngageTimer < -1)
245 else if (nAutoEngageTimer != -1 &&
246 --nAutoEngageTimer == 0)
248 }
249 if (bEngageAllowed != 0) {
250 engage(obj, nTargetShip,
252 } else if (obj == nYourWingman &&
253 nAutoEngageTimer == -1) {
254 send_message(obj, 3);
255 nAutoEngageTimer = 40;
256 }
257 } else if (obj == nYourWingman &&
259 any_enemy(obj, 16000) != 0 &&
260 message_showing() == 0 && nCameraViewMode == 0) {
261 send_message(obj, 2);
263 }
264
266 if (distance_from_object(obj, leader) > 9000)
267 if (facing_to_object(obj, &aShipPositionsArray[leader]) > 85 &&
268 real_velocity(obj) < 110)
269 fire_afterburner(obj, 10);
270 else {
271 point_ship_at_object(obj, leader);
272 approach_ship_speed(obj, leader);
273 }
274}
275
276/* Function start: 0x409F00 */
277void formation_break(short obj)
278{
279 switch (acShipSequence[obj]) {
280 case 0:
281 steady_object(obj);
282 anYawTarget[obj] = -30;
283 anRollGoal[obj] = -45;
284 anPitchGoal[obj] = -20;
285 acShipSequence[obj]++;
286 break;
287 case 1:
288 if (no_goal(obj) != 0)
289 engage(obj, acShipTargetTable[obj],
291 break;
292 default:
293 acShipSequence[obj] = 0;
294 break;
295 }
296}
297
298/* Function start: 0x409F80 */
299void imperial_wingman(short obj)
300{
301 switch (aeShipObjectiveList[obj]) {
304 break;
307 break;
310 break;
312 formation_break(obj);
313 break;
314 case OBJECTIVE_NONE:
316 break;
317 default:
318 fail(obj);
319 break;
320 }
321}
322
323/* Function start: 0x40A030 */
324void kilrathi_wingman(short obj)
325{
326 short leader = asShipWingLeaderArray[obj];
327 enum ShipObjective objective;
328
329 if (leader == -1) {
331 return;
332 }
333 if (unactive(leader) != 0) {
334 inherit_leader(obj);
335 return;
336 }
337 objective = aeShipObjectiveList[leader];
338 if ((objective == OBJECTIVE_ENGAGE_ENEMY ||
339 objective == OBJECTIVE_DESTROY_SHIP) &&
340 aeShipObjectiveList[obj] != objective)
341 engage(obj, acShipTargetTable[obj], objective);
342
343 switch (aeShipObjectiveList[obj]) {
347 break;
350 break;
352 formation_burst(obj);
353 break;
354 case OBJECTIVE_NONE:
356 break;
357 default:
358 fail(obj);
359 break;
360 }
361}
362
363/* Function start: 0x40A130 */
364void wingman_mission(short obj)
365{
366 if (aeShipSide[obj] == SIDE_IMPERIAL) {
367 imperial_wingman(obj);
368 return;
369 }
370 kilrathi_wingman(obj);
371}
372
373/* Function start: 0x40A160 */
374short dist_from_home(short obj)
375{
377}
378
379short scan_for_enemy(short obj, unsigned short range);
380
381/* Function start: 0x40A180 */
382short scan_and_lock(short obj, int scanRange, enum ShipTactic newTactic)
383{
384 acShipTargetTable[obj] = scan_for_enemy(obj, 14000);
385 if (acShipTargetTable[obj] != -1)
386 aeShipTacticArray[obj] = newTactic;
387 return acShipTargetTable[obj] != -1;
388}
389
390/* Function start: 0x40A1C0 */
391void patrol_area(short obj)
392{
393 short target = acShipTargetTable[obj];
394
395 switch (aeShipTacticArray[obj]) {
396 case TACTIC_HEAD_HOME:
398 if (scan_and_lock(obj, 14000, TACTIC_APPROACH_TARGET) == 0) {
400 if (nTgtRange < 3000) {
402 return;
403 }
405 trim_goals(obj, 7);
406 }
407 break;
408 case TACTIC_LOOK_OUT:
410 if (scan_and_lock(obj, 14000, TACTIC_APPROACH_TARGET) == 0 &&
411 dist_from_home(obj) > 8000)
413 break;
416 if (unactive(target) != 0) {
417 if (scan_and_lock(obj, 14000,
420 } else {
421 ship_vs_ship(obj, target);
422 if (nTgtRange < 10000) {
424 return;
425 }
426 if (no_goal(obj) != 0)
427 point_ship_at_object(obj, target);
428 }
429 break;
430 case TACTIC_NONE:
432 break;
433 default:
434 fail(obj);
435 break;
436 }
437}
438
439/* Function start: 0x40A360 */
440void kilrathi_patrol(short obj)
441{
442 switch (aeShipObjectiveList[obj]) {
443 case OBJECTIVE_WANDER:
445 patrol_area(obj);
446 break;
449 break;
451 formation_burst(obj);
452 break;
453 case OBJECTIVE_NONE:
456 break;
457 default:
458 fail(obj);
459 break;
460 }
461}
462
463/* Function start: 0x40A400 */
464void imperial_wingleader(short obj)
465{
466 kilrathi_patrol(obj);
467}
468
469/* Function start: 0x40A410 */
471{
472 short range;
473
474 if (abandoned(obj, 0) != 0)
475 return;
476
477 if ((abShipTurnList[obj] & 7) == 6)
478 acShipTargetTable[obj] = scan_for_enemy(obj, 15000);
479
480 if (acShipTargetTable[obj] == -1) {
482 } else {
484 if (nFacingToTargetValue > 65)
486 else
488 }
489
490 if ((abShipTurnList[obj] & 7) == 2) {
491 if (no_goal(obj) != 0)
494 if (range < 1500) {
495 if (aeShipSide[obj] == SIDE_IMPERIAL)
498 &aShipMissionSpotArray[obj])) {
501 } else {
503 }
504 }
505 }
506}
507
508/* Function start: 0x40A540 */
509void prepare_for_jump(short obj)
510{
511 if (anShipSpeed[obj] != 0) {
513 } else if (++asShipTotal[obj] >
514 (aeShipSide[obj] == SIDE_KILRATHI ? 250 : 25)) {
516 if (nFacingToTargetValue > 90 && no_goal(obj) != 0) {
517 anYawTarget[obj] = signed_random(30);
518 } else if (asShipTotal[obj] >
519 (aeShipSide[obj] == SIDE_KILRATHI ? 270 : 45) ||
520 (nTargetFacingValue > 80 && nTgtRange < 6000)) {
522 fire_afterburner(obj, 10);
523 }
524 }
525}
526
527/* Function start: 0x40A630 */
528void accelerate_and_jump(short obj)
529{
531 if (asShipTotal[obj]++ == 4)
532 warp(obj);
533}
534
535/* Function start: 0x40A670 */
536void reach_warp(short obj)
537{
538 switch (aeShipTacticArray[obj]) {
539 case TACTIC_CRUISE:
541 break;
542 case TACTIC_SIT_STILL:
543 prepare_for_jump(obj);
544 break;
545 case TACTIC_WARP_OUT:
547 break;
548 case TACTIC_NONE:
551 break;
552 default:
553 fail(obj);
554 break;
555 }
556}
557
558/* Function start: 0x40A710 */
559void warp_arrival(short obj)
560{
562 arrive_from_warp(obj);
563 else
565}
566
567/* Function start: 0x40A740 */
568void return_to_buddy(short obj, short buddy)
569{
571 if (no_goal(obj) != 0)
572 point_ship_at_object(obj, buddy);
573 if (distance_from_object(obj, buddy) < 1000) {
575 point_parallel(obj, buddy);
576 }
577}
578
579/* Function start: 0x40A7A0 */
580void escort_buddy(short obj, short buddy)
581{
582 approach_ship_speed(obj, buddy);
583 if (no_goal(obj) != 0)
584 point_parallel(obj, buddy);
585}
586
587/* Function start: 0x40A7D0 */
588void escort_mission(short obj)
589{
590 short buddy = find_ship_index(anShipMissionShips[obj]);
591
592 if (unactive(buddy) != 0) {
594 return;
595 }
596 if ((abShipTurnList[obj] & 3) == 0 && in_danger(buddy) != 0 &&
597 nTgtRange < 3000)
598 engage(obj, nTargetShip,
601 (abShipTurnList[obj] & 7) == 4 &&
602 distance_from_object(obj, buddy) > 5000)
604
605 switch (aeShipObjectiveList[obj]) {
607 return_to_buddy(obj, buddy);
608 break;
609 case OBJECTIVE_WANDER:
610 escort_buddy(obj, buddy);
611 break;
614 break;
615 case OBJECTIVE_NONE:
617 break;
618 default:
619 fail(obj);
620 break;
621 }
622}
623
624/* Function start: 0x40A900 */
625void check_goal(short obj)
626{
627 if (gone_ship(anShipMissionShips[obj]) != 0)
629 else
631}
632
633/* Function start: 0x40A940 */
634void streak_toward(short obj, short goal, short range)
635{
636 if (no_goal(obj) != 0) {
637 if (RandomBelow(100) < 95)
638 point_ship_at_object(obj, goal);
639 else
640 veer_random(obj, 20);
641 }
642 if (range > 2000 && normal_speed(obj) != 0)
643 fire_afterburner(obj, 10);
644 else
646}
647
648/* Function start: 0x40A9B0 */
649void approach_and_engage(short obj, short goal)
650{
651 unsigned short range = (unsigned short)distance_from_object(obj, goal);
652 unsigned short possibleRange;
653 short possibleTarget;
654
656 evaluate_damage(obj) > 70 - MaxShort(
657 0, MinShort(4, (short)aiPilotLevel[obj])) * 15 &&
658 range > 5000) {
659 streak_toward(obj, goal, (short)range);
660 return;
661 }
662 possibleTarget = scan_for_enemy(obj, 10000);
663 possibleRange = (unsigned short)nTgtRange;
664 if (possibleTarget != -1 &&
665 (possibleRange * 3 < range ||
668 acShipTargetTable[obj] = possibleTarget;
669 } else if (range < 5000) {
670 engage(obj, goal, OBJECTIVE_DESTROY_SHIP);
671 } else {
672 streak_toward(obj, goal, (short)range);
673 }
674}
675
676/* Function start: 0x40AAC0 */
677void strike_mission(short obj)
678{
679 short goal = find_ship_index(anShipMissionShips[obj]);
680
681 if (goal == -1 &&
683 check_goal(obj);
684 switch (aeShipObjectiveList[obj]) {
687 approach_and_engage(obj, goal);
688 break;
691 break;
694 break;
696 formation_burst(obj);
697 break;
698 case OBJECTIVE_NONE:
700 break;
701 default:
702 fail(obj);
703 break;
704 }
705}
706
707/* Function start: 0x40ABB0 */
708void return_to_master(short obj, short master)
709{
710 short range = distance_from_object(obj, master);
711
712 streak_toward(obj, master, range);
713 if (range < 5000) {
715 point_perpendicular(obj, master);
716 }
717}
718
719/* Function start: 0x40AC00 */
720void defend_mission(short obj)
721{
722 short master = find_ship_index(anShipMissionShips[obj]);
723
724 if (master == -1) {
726 return;
727 }
728
729 if (abShipTurnList[obj] % 10 == 0)
730 if (in_danger(master) != 0)
731 if (nTgtRange < 6000) {
734 }
735
737 if ((abShipTurnList[obj] & 7) == 4)
738 if (distance_from_object(obj, master) > 10000)
740
741 switch (aeShipObjectiveList[obj]) {
742 case OBJECTIVE_WANDER:
743 acShipTargetTable[obj] = scan_for_enemy(obj, 7000);
744 if (acShipTargetTable[obj] != -1)
746 else {
748 if (no_goal(obj) != 0)
749 point_perpendicular(obj, master);
750 }
751 break;
753 return_to_master(obj, master);
754 break;
757 break;
758 case OBJECTIVE_NONE:
760 break;
761 default:
762 fail(obj);
763 }
764}
765
766/* Function start: 0x40AD80 */
767void rendezvous_mission(short obj)
768{
769 short goal = find_ship_index(anShipMissionShips[obj]);
770
771 if (unactive(goal) != 0) {
773 return;
774 }
775 switch (aeShipObjectiveList[obj]) {
777 if (attacker_in_range(obj, 3500) != 0)
778 engage(obj, nTargetShip,
780 if (distance_from_object(obj, goal) < 2500) {
782 return;
783 }
784 if (attacker_in_range(goal, 9000) != 0)
786 else
788 if (no_goal(obj) != 0)
789 point_ship_at_object(obj, goal);
790 break;
793 break;
794 default:
796 break;
797 }
798}
799
800/* Function start: 0x40AE80 */
801void ship_intelligence(short obj)
802{
803 short target;
804
805 if (regulate_turn(obj) != 0)
806 return;
807 switch (aeShipMissionType[obj]) {
809 /* The retail source tests the array address rather than this ship's
810 * side, leaving the Imperial arm present but unreachable. */
811 if (aeShipSide == 0)
813 else
814 kilrathi_patrol(obj);
815 break;
817 escort_mission(obj);
818 break;
820 strike_mission(obj);
821 break;
823 defend_mission(obj);
824 break;
826 wingman_mission(obj);
827 break;
829 run_away(obj);
830 break;
832 reach_warp(obj);
833 break;
835 warp_arrival(obj);
836 break;
839 break;
841 coming_home(obj);
842 break;
845 break;
846 default:
847 fail(obj);
848 break;
849 }
850 if (acShipAiCooldowns[obj] > 0)
851 acShipAiCooldowns[obj]--;
852}
853
854/* Function start: 0x40AF70 */
855void orbit_sphere(short obj)
856{
857 short radius = aMissionNavPoints[
859 FixedVector center =
861 short range = distance_from_point(obj, &center);
862
863 if (no_goal(obj) != 0)
864 if (range > radius - 750)
865 if (range > radius)
866 point_ship_at_point(obj, &center);
867 else
868 point_perpendicular_to_point(obj, &center);
869 trim_goals(obj, 10);
870}
871
872/* Function start: 0x40B010 */
873void tanker_intelligence(short obj)
874{
875 if (attacker_in_range(obj, 3000) != 0) {
878 fire(obj, nTargetShip);
879 if (no_goal(obj) != 0) {
880 if (RandomBelowOrEqual(4) == 0) {
881 anYawTarget[obj] = signed_random(90);
882 anRollGoal[obj] = signed_random(90);
883 } else {
886 }
887 }
888 return;
889 }
891 orbit_sphere(obj);
892}
893
894/* Function start: 0x40B0C0 */
896{
897 if (fire_turrets(obj) != 0) {
898 acShipTargetTable[obj] = -1;
900 } else {
902 }
903 orbit_sphere(obj);
904}
905
906/* Function start: 0x40B110 */
908{
910 anObjectYawRotation[obj] = 4;
911 fire_turrets(obj);
912 }
913}
914
915/* Function start: 0x40B140 */
917{
918 if (regulate_turn(obj) != 0)
919 return;
920 switch (aeShipMissionType[obj]) {
922 run_away(obj);
923 return;
925 reach_warp(obj);
926 return;
928 warp_arrival(obj);
929 return;
931 coming_home(obj);
932 return;
935 return;
936 default:
937 break;
938 }
939
943 return;
944 }
952 return;
953 }
954
955 if (unactive(nTargetShip = acShipTargetTable[obj]) != 0)
956 scan_for_enemy(obj, 15000);
957 switch (aeShipTacticArray[obj]) {
960 if (unactive(acShipTargetTable[obj]) != 0) {
961 select_target(obj);
962 if (unactive(acShipTargetTable[obj]) != 0)
964 } else
965 fire_turrets(obj);
966 break;
967 default:
968 if (nTargetShip != -1) {
971 acShipTargetTable[obj] = (signed char)nTargetShip;
972 fire_turrets(obj);
973 } else
975 }
976}
977
978/* Function start: 0x40B320 */
980{
981 ship_vs_ship(0, obj);
982
983 asActionCounts[obj]++;
984 if (nTgtRange > 1000 && asActionCounts[obj] > 1000)
986 else if (asActionCounts[obj] > 200 && nTgtRange < 4000 &&
987 nTgtRange > 1000 && nFacingToTargetValue > 80)
989}
990
991/* Function start: 0x40B3A0 */
992void mine_intelligence(short obj)
993{
994 short other;
995 short distance;
996 int objectIndex = obj;
997
998 if (asObjectCounterArray[objectIndex] != -1)
999 return;
1000 for (other = 0; other <= 9; other++) {
1001 if (other == obj || aeObjectClass[other] <
1003 continue;
1004 distance = distance_from_object(obj, other);
1005 if (distance < aObjectTypeData[
1006 aeObjectTypeList[objectIndex]].collisionRadius ||
1007 (distance < 50 && RandomBelowOrEqual(7) == 0)) {
1008 explode(obj, obj);
1009 return;
1010 }
1011 }
1012}
1013
1014unsigned int sort_viable_target_list(void);
1015short get_ship_max_velocity(short obj);
1016
1017/* Function start: 0x40B430 */
1019{
1020 short exhaustHeat;
1021 short targetShip;
1022 short targ;
1023
1024 if (nFacingToTargetValue < 0 || acShipTargetTable[obj] == -1) {
1025 acShipTargetTable[obj] = -1;
1027 for (targetShip = 0; targetShip <= 9; targetShip++) {
1028 if (obj != targetShip &&
1029 aeObjectClass[targetShip] >= OBJECT_CLASS_SHIP) {
1030 get_facing_range_from_object(obj, targetShip);
1032 nTargetFacingValue < 0) {
1034 nTgtRange;
1035 acViableTargetList[cViableTargetCount++] = targetShip;
1036 }
1037 }
1038 }
1040 if (cViableTargetCount > 0) {
1041 for (exhaustHeat = 3; exhaustHeat > 0; exhaustHeat--) {
1042 for (targ = 0; targ < cViableTargetCount; targ++) {
1043 if (aeObjectClass[acViableTargetList[targ]] ==
1046 exhaustHeat) {
1048 exhaustHeat = 0;
1049 break;
1050 }
1051 }
1052 }
1053 }
1054 if (acShipTargetTable[obj] == -1)
1055 explode(obj, obj);
1056 } else {
1057 point_ship(obj, 0, &vToTgt);
1058 anShipSpeed[obj] =
1059 (get_ship_max_velocity(obj) + 10) << 8;
1060 }
1061}
1062
1063/* Function start: 0x40B570 */
1065{
1066 short targetShip;
1067
1068 if (aeShipTacticArray[obj] == TACTIC_RAM) {
1069 if (acShipTargetTable[obj] == -1) {
1071 for (targetShip = 0; targetShip <= 9; targetShip++) {
1072 if (obj != targetShip) {
1073 if (aeObjectClass[targetShip] >= OBJECT_CLASS_SHIP) {
1074 if (aeShipSide[targetShip] !=
1076 acShipCommunicatorArray[targetShip] == -1) {
1077 nTgtRange =
1078 distance_from_object(obj, targetShip);
1079 if (nTgtRange < 9000) {
1083 targetShip;
1084 }
1085 }
1086 }
1087 }
1088 }
1090 if (cViableTargetCount > 0)
1092 } else {
1093 point_ship(obj, 0, &vToTgt);
1094 anShipSpeed[obj] =
1095 (get_ship_max_velocity(obj) + 10) << 8;
1096 }
1097 }
1098}
short asViableTgtDistList[16]
Definition game.c:555
enum ShipTactic aeShipTacticArray[12]
Definition input.c:20
MissionHeaderDisk stCurrentMissionHeader
Definition mission.c:57
short anShipMissionShips[16]
Definition comm.c:57
signed char abShipExhaustHeatList[10]
Definition input.c:21
short nCurrentWave
Definition game.c:34
int nCameraViewMode
Definition game.c:49
signed char acViableTargetList[16]
Definition dib.c:102
enum Side aeShipSide[12]
Definition ending.c:22
short anRollGoal[16]
Definition ending.c:21
short nEnemySighting
Definition brains.c:20
ObjectTypeData aObjectTypeData[OBJECT_TYPE_COUNT]
Definition objdata.c:86
signed char abShipNavPtIdx[16]
Definition screen.c:14
int aiPilotLevel[12]
Definition video.c:16
short asShipTotal[16]
Definition game.c:551
short anPitchGoal[16]
Definition screen.c:13
signed char cViableTargetCount
Definition game.c:107
short anObjectYawRotation[SPACE_OBJECT_COUNT]
Definition joycal.c:33
short nFuneralCasketPosY
Definition brains.c:27
FixedVector aShipDestinationsArray[10]
Definition input.c:18
short nTgtRange
Definition joycal.c:27
signed char abFlightPathList[MISSION_OBJECTIVE_COUNT]
Definition smart.c:20
signed char abShipTurnList[16]
Definition screen.c:17
short nFacingToTargetValue
Definition screen.c:19
FixedVector vToTgt
Definition comm.c:58
struct Shape * pScrambleDetailShape
Definition brains.c:23
enum ShipMissionType aeShipMissionType[12]
Definition game.c:550
ShortPoint stScrambleCockpitDetail
Definition brains.c:25
enum ShipObjective aeShipObjectiveList[12]
Definition video.c:22
MissionNavPoint aMissionNavPoints[MISSION_NAV_POINT_COUNT]
Definition game.c:199
enum ObjectClass aeObjectClass[SPACE_OBJECT_COUNT]
Definition video.c:21
short nYourWingman
Definition game.c:61
FixedVector aShipVelocity[SPACE_OBJECT_COUNT]
Definition smart.c:21
FixedVector aShipMissionSpotArray[10]
Definition screen.c:27
short nScrambleCockpitAngle
Definition brains.c:24
int anShipSpeed[64]
Definition data.c:248
short asShipWingLeaderArray[16]
Definition comm.c:51
short nTargetFacingValue
Definition input.c:17
short asObjectCounterArray[SPACE_OBJECT_COUNT]
Definition game.c:547
signed char acObjOwnersTable[64]
Definition joycal.c:29
MissionObjective aMissionObjectivesArray[MISSION_OBJECTIVE_COUNT]
Definition screen.c:24
short nFuneralCasketPositionX
Definition brains.c:26
int bEngageAllowed
Definition game.c:101
short nCurrentNavigationPoint
Definition music.c:90
enum ObjectType aeObjectTypeList[SPACE_OBJECT_COUNT]
Definition data.c:255
char acShipSequence[10]
Definition input.c:16
FixedVector aShipPositionsArray[SPACE_OBJECT_COUNT]
Definition game.c:556
short nTargetShip
Definition game.c:548
signed char acShipTargetTable[16]
Definition joycal.c:30
signed char acShipCommunicatorArray[16]
Definition game.c:560
short anYawTarget[16]
Definition smart.c:22
short nAutoEngageTimer
Definition game.c:104
enum SpecialManeuver aeSpecialManeuvers[12]
Definition game.c:549
short asActionCounts[10]
Definition dib.c:103
signed char acShipAiCooldowns[16]
Definition ending.c:23
short homeMissionShip
Definition wcdata.h:564
FixedVector position
Definition wcdata.h:859
short proximityRadius
Definition wcdata.h:860
FixedVector position
Definition wcdata.h:931
Umbrella header for the game core.
unsigned int approach_full_speed(short ship)
Definition logic.c:779
void imperial_wingman(short obj)
Definition brains.c:299
unsigned int select_target(short obj)
Definition smart.c:154
void approach_and_engage(short obj, short goal)
Definition brains.c:649
void escort_buddy(short obj, short buddy)
Definition brains.c:580
void kilrathi_patrol(short obj)
Definition brains.c:440
unsigned int reset_objective(short ship, enum ShipObjective objective)
Definition logic.c:676
void cruise_to_destination(short obj)
Definition brains.c:470
void formation_burst(short obj)
Definition brains.c:180
unsigned int get_first_follow_point(short obj, FixedVector *point)
Definition logic.c:1260
void point_ship_at_object(short obj, short other)
Definition geom.c:812
short distance_from_point(short obj, const FixedVector *point)
Definition geom.c:655
void perform_maneuver(short obj)
Definition fl.c:939
void ship_vs_ship(short obj, short other)
Definition geom.c:710
unsigned int steady_object(short ship)
Definition ship.c:422
void engage(short obj, short target, enum ShipObjective objective)
Definition logic.c:1306
void warp_arrival(short obj)
Definition brains.c:559
void imperial_formation(short obj)
Definition brains.c:230
void remove_object(short obj)
Definition geom.c:1002
void fire_afterburner(short obj, short time)
Definition ship.c:1976
void formation_break(short obj)
Definition brains.c:277
void disallow_engage(void)
Definition brains.c:197
void maneuvering(short obj, short newTarget)
Definition brains.c:172
unsigned int warp(short obj)
Definition targ.c:87
short evaluate_damage(short obj)
Definition logic.c:1366
void wingman_mission(short obj)
Definition brains.c:364
void patrol_area(short obj)
Definition brains.c:391
int abandoned(short obj, short other)
Definition logic.c:1286
void point_capital_ship_at_object(short obj, short other)
Definition geom.c:818
void accelerate_and_jump(short obj)
Definition brains.c:528
void flag_reached(short objective, short reached)
Definition cockpt.c:1249
void kilrathi_wingman(short obj)
Definition brains.c:324
void run_away(short obj)
Definition brains.c:105
int equ_vector(const FixedVector *left, const FixedVector *right)
Definition geom.c:267
int fire_turrets(short obj)
Definition ship.c:1682
void escort_mission(short obj)
Definition brains.c:588
void rendezvous_mission(short obj)
Definition brains.c:767
void FF_missile_intelligence(short obj)
Definition brains.c:1064
short MinShort(short a, short b)
Definition mathutil.c:20
short scan_for_enemy(short obj, unsigned short range)
Definition logic.c:856
void return_to_master(short obj, short master)
Definition brains.c:708
void cruise_home(short obj)
Definition brains.c:30
short get_ship_max_velocity(short obj)
Definition geom.c:95
short find_objective(int type, short index)
Definition targ.c:26
void point_ship(short obj, short turnRate, const FixedVector *direction)
Definition geom.c:793
unsigned int approach_ship_speed(short obj, short other)
Definition logic.c:787
void strike_mission(short obj)
Definition brains.c:677
unsigned int approach_half_speed(short obj)
Definition logic.c:760
void defend_mission(short obj)
Definition brains.c:720
short distance_from_object(short obj, short other)
Definition geom.c:667
int explode(short attacker, short victim)
Definition ship.c:1340
void fail(short obj)
Definition brains.c:69
void imperial_wingleader(short obj)
Definition brains.c:464
void inherit_leader_mission(short obj)
Definition logic.c:1093
void streak_toward(short obj, short goal, short range)
Definition brains.c:634
unsigned int init_formation_burst(short obj)
Definition logic.c:627
void prepare_for_jump(short obj)
Definition brains.c:509
short signed_random(short range)
Definition logic.c:160
void point_perpendicular(short obj, short other)
Definition geom.c:860
void check_goal(short obj)
Definition brains.c:625
void point_perpendicular_to_point(short obj, const FixedVector *point)
Definition geom.c:850
unsigned int set_special(short ship, enum SpecialManeuver special)
Definition logic.c:729
unsigned int change_mission_type(short obj, enum ShipMissionType missionType)
Definition logic.c:665
void intelligence_events(short obj)
Definition smart.c:599
unsigned int sort_viable_target_list(void)
Definition ship.c:447
signed char no_goal(short ship)
Definition logic.c:495
void ship_vs_point(short obj, const FixedVector *point)
Definition geom.c:704
void send_message(short obj, short message)
Definition cockpt.c:2489
int attacker_in_range(short obj, unsigned short range)
Definition logic.c:979
short facing_to_object(short obj, FixedVector *point)
Definition geom.c:716
void zero_vector(FixedVector *vector)
Definition geom.c:280
int gone_ship(short missionShip)
Definition logic.c:1134
void try2allow_engage(int pilotLevel)
Definition brains.c:210
short real_velocity(short obj)
Definition ship.c:431
unsigned int alter_tactic(short ship, enum ShipTactic tactic)
Definition logic.c:704
void ship_intelligence(short obj)
Definition brains.c:801
int in_danger(short obj)
Definition logic.c:1006
short RandomBelow(short n)
Definition mathfp.c:29
int any_enemy(short obj, short range)
Definition logic.c:887
unsigned int veer_random(short obj, short amount)
Definition smart.c:172
short detect_enemy_tail(short obj)
Definition logic.c:535
void get_facing_range_from_object(short obj, short other)
Definition geom.c:691
int regulate_turn(short obj)
Definition smart.c:135
short dist_from_home(short obj)
Definition brains.c:374
unsigned int get_follow_point(short obj, FixedVector *point)
Definition logic.c:1224
unsigned int approach_cruise_speed(short ship)
Definition logic.c:770
void capital_ship_intelligence(short obj)
Definition brains.c:916
void futurion_intelligence(short obj)
Definition brains.c:979
void fire(short obj, short target)
Definition ship.c:1445
void arrive_from_warp(short obj)
Definition targ.c:42
void reach_warp(short obj)
Definition brains.c:536
unsigned int reset_tactic(short ship, enum ShipTactic tactic)
Definition logic.c:694
void inherit_leader(short obj)
Definition logic.c:1110
void mine_intelligence(short obj)
Definition brains.c:992
void flag_objective(short objective, unsigned char flags)
Definition cockpt.c:1048
void allow_engage(void)
Definition brains.c:203
void tanker_intelligence(short obj)
Definition brains.c:873
unsigned int reset_mission_type(short obj, enum ShipMissionType missionType)
Definition logic.c:653
void stationary_intelligence(short obj)
Definition brains.c:907
void heat_seeking_missile_intelligence(short obj)
Definition brains.c:1018
void destroyer_intelligence(short obj)
Definition brains.c:895
short MaxShort(short a, short b,...)
Definition mathutil.c:29
unsigned int maintain_formation(short obj)
Definition smart.c:367
int target_valid(short obj)
Definition logic.c:1319
short check_engage_target(short obj)
Definition brains.c:135
void coming_home(short obj)
Definition brains.c:75
short check_destroy_target(short obj)
Definition brains.c:147
short normal_speed(short obj)
Definition logic.c:220
short find_ship_index(short missionShip)
Definition logic.c:439
int trim_goals(short obj, short amount)
Definition logic.c:372
void return_to_buddy(short obj, short buddy)
Definition brains.c:568
void point_ship_at_point(short obj, const FixedVector *point)
Definition geom.c:802
void orbit_sphere(short obj)
Definition brains.c:855
void point_parallel(short obj, short other)
Definition geom.c:866
short RandomBelowOrEqual(short n)
Definition mathfp.c:59
unsigned int unactive(short ship)
Definition logic.c:353
short scan_and_lock(short obj, int scanRange, enum ShipTactic newTactic)
Definition brains.c:382
short message_showing(void)
Definition cockpt.c:776
ShipMissionType
Definition wcdata.h:120
@ MISSION_TYPE_PATROL
Definition wcdata.h:122
@ MISSION_TYPE_ESCORT
Definition wcdata.h:123
@ MISSION_TYPE_WARP_ARRIVE
Definition wcdata.h:129
@ MISSION_TYPE_GOTO_WARP
Definition wcdata.h:128
@ MISSION_TYPE_RENDEZVOUS
Definition wcdata.h:131
@ MISSION_TYPE_WINGMAN
Definition wcdata.h:126
@ MISSION_TYPE_ROUT
Definition wcdata.h:127
@ MISSION_TYPE_DEFEND
Definition wcdata.h:125
@ MISSION_TYPE_COME_HOME
Definition wcdata.h:132
@ MISSION_TYPE_NONE
Definition wcdata.h:121
@ MISSION_TYPE_STRIKE
Definition wcdata.h:124
@ OBJECT_TYPE_KILRATHI_BASE
Definition wcdata.h:76
@ OBJECT_TYPE_FRALTHI
Definition wcdata.h:73
@ OBJECT_TYPE_LUMBARI
Definition wcdata.h:71
@ OBJECT_TYPE_SNAKEIR
Definition wcdata.h:74
@ OBJECT_TYPE_RALARI
Definition wcdata.h:72
@ OBJECT_TYPE_SPIKERI
Definition wcdata.h:69
@ OBJECT_TYPE_DORKIR
Definition wcdata.h:70
@ OBJECT_TYPE_SIVAR
Definition wcdata.h:75
@ SIDE_IMPERIAL
Definition wcdata.h:174
@ SIDE_KILRATHI
Definition wcdata.h:175
ShipObjective
Definition wcdata.h:136
@ OBJECTIVE_ENGAGE_ENEMY
Definition wcdata.h:144
@ OBJECTIVE_DESTROY_SHIP
Definition wcdata.h:142
@ OBJECTIVE_HOLD_FORMATION
Definition wcdata.h:146
@ OBJECTIVE_REACH_SHIP
Definition wcdata.h:141
@ OBJECTIVE_BREAK_FORMATION
Definition wcdata.h:147
@ OBJECTIVE_WANDER
Definition wcdata.h:143
@ OBJECTIVE_HOME_BASE
Definition wcdata.h:139
@ OBJECTIVE_NONE
Definition wcdata.h:137
@ SPECIAL_MANEUVER_STOP_DRIFT
Definition wcdata.h:265
@ SPECIAL_MANEUVER_KILL_ENGINES
Definition wcdata.h:264
@ SPECIAL_MANEUVER_NONE
Definition wcdata.h:258
ObjectClass
Definition wcdata.h:37
@ OBJECT_CLASS_SHIP
Definition wcdata.h:50
@ OBJECT_CLASS_CAPITAL_SHIP
Definition wcdata.h:51
@ OBJECT_CLASS_FUTURION
Definition wcdata.h:39
ShipTactic
Definition wcdata.h:150
@ TACTIC_SELF_DEFENSE
Definition wcdata.h:168
@ TACTIC_HEAD_HOME
Definition wcdata.h:160
@ TACTIC_APPROACH_TARGET
Definition wcdata.h:163
@ TACTIC_CRUISE
Definition wcdata.h:152
@ TACTIC_WARP_OUT
Definition wcdata.h:158
@ TACTIC_NONE
Definition wcdata.h:151
@ TACTIC_WARP_IN
Definition wcdata.h:159
@ TACTIC_LOOK_OUT
Definition wcdata.h:162
@ TACTIC_RAM
Definition wcdata.h:156
@ TACTIC_SIT_STILL
Definition wcdata.h:153