Wing Commander II
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
logic.c
Go to the documentation of this file.
1/*
2 * Ship AI bookkeeping: alerts, collisions, goals and squads.
3 *
4 * Retail object 0x429550-0x42BABF (link order; see docs/ORDER.md).
5 */
6#define LOGIC_C
7#include "game.h"
8
9/* Function start: 0x429550 */
11{
13 send_message(obj, 0x17);
15 }
16}
17
18/* Function start: 0x429581 */
19short signed_random(short range)
20{
21 return RandomBelowOrEqual((short)(range * 2)) - range;
22}
23
24/* Function start: 0x4295A9 */
25short alert_flag(short ship, unsigned int bits)
26{
27 return (g_anShipAlertFlags[ship] & bits) != 0;
28}
29
30/* Function start: 0x4295D9 */
31void set_alert(short i, unsigned int bits)
32{
33 g_anShipAlertFlags[i] |= bits;
34}
35
36/* Function start: 0x4295F2 */
37void clear_alert(short i)
38{
39 g_anShipAlertFlags[i] = 0;
40 g_acShipAlertSource[i] = -1;
42}
43
44/* Function start: 0x429625 */
45void start_collision_alert(short obj, short other)
46{
47 if ((short)g_acShipAlertSource[obj] != other) {
48 g_acShipAlertSource[obj] = (signed char)other;
49 steady_object(obj);
50 }
52 set_alert(obj, 1);
55}
56
57/* Function start: 0x429698 */
59{
61 if (g_asShipAlertCountdown[obj] <= 0)
62 clear_alert(obj);
63 else
64 set_alert(obj, 2);
65}
66
67/* Function start: 0x4296E2 */
68short normal_speed(short obj)
69{
70 return g_aeSpecialManeuver[obj] !=
73}
74
75/* Function start: 0x429736 */
76short real_crash_time(short obj, short other)
77{
78 short crash;
79 short gap;
80 short contactRange;
81 short time;
82 long speed;
83 FixedVector future;
84 long startDistance;
85 FixedVector relativeVelocity;
86 FixedVector currentOffset;
87 FixedVector travelled;
88 short checkTime;
89
90 crash = 0;
91 contactRange = (short)(g_asObjectCollisionRadius[obj] +
92 g_asObjectCollisionRadius[other] + 30);
94 &g_aShipPosition[other],
95 &currentOffset);
96 startDistance = Vector_magnitude(&currentOffset);
98 &g_aShipVelocity[other],
99 &relativeVelocity);
100 speed = Vector_magnitude(&relativeVelocity);
101 if (speed == 0)
102 return 0x7fbc;
103
105 DivideFixed((int)startDistance, (int)speed));
106 if (time >= 30)
107 return time;
108
109 ScaleFixedVector(&relativeVelocity, (int)time << 8, &travelled);
110 AddFixedVectors(&currentOffset, &travelled, &future);
112 if (contactRange < gap) {
113 if ((contactRange + contactRange) >> 4 > gap)
114 return 25;
115 else
116 return 32000;
117 }
118
119 checkTime = 0;
120 while (crash == 0 && checkTime < time) {
121 checkTime += MaxShort(1, (short)((time - checkTime) >> 1));
122 ScaleFixedVector(&relativeVelocity, (int)checkTime << 8, &travelled);
123 AddFixedVectors(&currentOffset, &travelled, &future);
125 if (contactRange >= gap)
126 crash = 1;
127 }
128 return checkTime;
129}
130
131/* Function start: 0x429958 */
132short crash_time(short obj, short other)
133{
135 (g_asObjectScreenX[other] == -0x7fff ||
136 g_asObjectScreenX[obj] == -0x7fff))
137 return 0x7fff;
138 else
139 return real_crash_time(obj, other);
140}
141
142/* Function start: 0x4299C9 */
143short detect_collisions(short obj)
144{
145 short object;
146 short time;
147 short soonest;
148 short candidate;
149
150 candidate = -1;
151 soonest = 30;
153 candidate = -1;
154 if (g_pActiveHazardField != 0) {
155 for (object = 0; object <= 0x42; object++) {
156 if (g_aeObjectClass[object] != OBJECT_CLASS_NULL &&
157 object != obj &&
160 time = crash_time(obj, object);
161 if (time < soonest) {
162 soonest = time;
163 candidate = object;
164 }
165 }
166 }
167 } else {
168 for (object = 0; object <= 9; object++) {
169 if (g_aeObjectClass[object] != OBJECT_CLASS_NULL &&
170 object != obj &&
172 time = crash_time(obj, object);
173 if (time < soonest) {
174 soonest = time;
175 candidate = object;
176 }
177 }
178 }
179 }
180 if (candidate != -1)
182 return candidate;
183}
184
185/* Function start: 0x429B55 */
186short unactive(short ship)
187{
188 return ship == -1 ||
191}
192
193/* Function start: 0x429BA8 */
194short are_alive(short obj)
195{
196 return unactive(obj) == 0 &&
198}
199
200/* Function start: 0x429BF0 */
201void trim_goals(short obj, short amount)
202{
203 if (g_anYawGoal[obj] > amount)
204 g_anYawGoal[obj] = amount;
205 else if (g_anYawGoal[obj] < -amount)
206 g_anYawGoal[obj] = -amount;
207 if (g_anPitchGoal[obj] > amount)
208 g_anPitchGoal[obj] = amount;
209 else if (g_anPitchGoal[obj] < -amount)
210 g_anPitchGoal[obj] = -amount;
211}
212
213/* Function start: 0x429CAD */
214short report_kilrathi_rout(int mode)
215{
216 short obj;
217
218 for (obj = 0; obj < 10; obj++) {
220 g_aeSpecialManeuver[obj] !=
222 switch (mode) {
223 case 0:
224 if (g_asShipSide[obj] == SIDE_KILRATHI)
225 return 1;
226 break;
227 case 1:
228 if (g_asShipSide[obj] == SIDE_KILRATHI &&
229 g_asShipMissionType[obj] !=
231 distance_from_object(0, obj) < 16000)
232 return 1;
233 break;
234 case 2:
235 if (g_asShipSide[obj] == SIDE_KILRATHI &&
236 (g_aeShipObjective[obj] ==
238 g_aeShipObjective[obj] ==
240 return 1;
241 break;
242 }
243 }
244 }
245 if (mode == 1 && g_nCurrentWave != -1)
247 return 0;
248}
249
250/* Function start: 0x429E24 */
251short find_ship_index(short missionShip)
252{
253 short obj;
254
255 g_nLastFoundShip = -1;
256 if (missionShip != -1) {
257 for (obj = 0; obj < 10; obj++) {
258 if (((g_aeObjectClass[obj] >= OBJECT_CLASS_SHIP &&
259 g_aeSpecialManeuver[obj] !=
262 g_asShipMissionIndex[obj] == missionShip) {
263 g_nLastFoundShip = obj;
264 return g_nLastFoundShip;
265 }
266 }
267 }
268 return g_nLastFoundShip;
269}
270
271/* Function start: 0x429EE0 */
272short try2rout(short obj)
273{
274 short other;
275 short hasBase;
276
277 hasBase = 0;
278 if (any_enemy(obj, 10000) != 0) {
279 for (other = 0; other < 10; other++) {
280 if (g_aeObjectClass[other] >=
282 g_aeSpecialManeuver[other] !=
284 g_asShipSide[other] ==
285 g_asShipSide[obj])
286 hasBase = 1;
287 }
288 }
289 if (hasBase != 0) {
290 g_acShipStress[obj] = 0;
292 } else {
294 if (obj == g_nYourWingman) {
296 send_message(obj, 0xb);
297 }
298 }
299 return (short)(hasBase == 0);
300}
301
302/* Function start: 0x42A003 */
303signed char CanSetNewShipTurnGoal(short ship)
304{
305 if (GetAdaptiveTurnRate() > 120)
306 return 1;
307 return (g_anYawGoal[ship] |
308 g_anPitchGoal[ship] |
309 g_anRollGoal[ship]) == 0;
310}
311
312/* Function start: 0x42A062 */
313signed char no_goal(short ship)
314{
315 return (g_anYawGoal[ship] |
316 g_anPitchGoal[ship] |
317 g_anRollGoal[ship]) == 0;
318}
319
320/* Function start: 0x42A0A9 */
321short being_tailed(short obj, short other)
322{
324 return g_nFacingToTarget < -70 &&
325 g_nTargetFacing > 90 &&
326 g_nTargetRange < 4000;
327}
328
329/* Function start: 0x42A108 */
330short detect_enemy_tail(short obj)
331{
332 short other;
333
334 for (other = 0; other < 10; other++) {
335 if (g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
336 g_aeSpecialManeuver[other] !=
338 g_asShipSide[obj] != g_asShipSide[other] &&
339 g_acShipTarget[other] == obj &&
340 being_tailed(obj, other) != 0)
341 return other;
342 }
343 return -1;
344}
345
346/* Function start: 0x42A1C5 */
348{
349 short target = g_acShipTarget[0];
350
351 if (unactive(target) == 0 && being_tailed(target, obj) != 0)
352 return 1;
353 return 0;
354}
355
356/* Function start: 0x42A222 */
358{
359 short other;
360
361 for (other = 0; other < 10; other++) {
363 g_acShipTarget[other] == obj)
364 return other;
365 }
366 return 0;
367}
368
369/* Function start: 0x42A28E */
370void build_squad_list(short leader)
371{
372 short index;
373 short obj;
374
375 index = 0;
376 g_acShipList[index++] = (signed char)leader;
377 g_acShipList[index] = -1;
378 for (obj = 0; obj < 10; obj++) {
379 if (g_asShipWingLeader[obj] == leader) {
380 g_acShipList[index++] = (signed char)obj;
381 g_acShipList[index] = -1;
382 }
383 }
384}
385
386/* Function start: 0x42A313 */
387unsigned int find_squad_center(FixedVector *center)
388{
389 short count;
390
391 zero_vector(center);
392 count = -1;
393 while (g_acShipList[++count] != -1) {
395 (short)g_acShipList[count]],
396 center);
397 }
398 if (count != 0)
399 divide_vector(center, (int)count << 8, center);
400}
401
402/* Function start: 0x42A39A */
403void init_formation_burst(short obj)
404{
405 FixedVector center;
406 short member;
407 short i;
408
409 i = -1;
410 build_squad_list(obj);
411 find_squad_center(&center);
412 while ((member = g_acShipList[++i]) != -1) {
413 ComputeVectorDelta(&center, &g_aShipPosition[member],
414 &g_aShipDestination[member]);
415 ScaleFixedVector(&g_aShipDestination[member], 0xa00,
416 &g_aShipDestination[member]);
418 &g_aShipPosition[member],
419 &g_aShipDestination[member]);
420 steady_object(member);
422 }
423}
424
425/* Function start: 0x42A490 */
426void reset_mission_type(short obj, short missionType)
427{
428 if (missionType == MISSION_TYPE_ROUT &&
432 g_asShipMissionType[obj] = missionType;
433}
434
435/* Function start: 0x42A4E5 */
436unsigned int change_mission_type(short obj, short missionType)
437{
439 g_asShipMissionType[obj] = missionType;
440 else
441 reset_mission_type(obj, missionType);
442}
443
444/* Function start: 0x42A52A */
445unsigned int reset_objective(short ship, short objective)
446{
447 steady_object(ship);
449 g_aeShipObjective[ship] = objective;
450}
451
452/* Function start: 0x42A55F */
453unsigned int alter_objective(short ship, short objective)
454{
455 steady_object(ship);
457 g_aeShipObjective[ship] = objective;
458}
459
460/* Function start: 0x42A594 */
461unsigned int reset_tactic(short ship, short tactic)
462{
464 g_asShipTactic[ship] = tactic;
465 g_acShipTarget[ship] = -1;
466}
467
468/* Function start: 0x42A5C8 */
469unsigned int alter_tactic(short ship, short tactic)
470{
472 g_asShipTactic[ship] = tactic;
473}
474
475/* Function start: 0x42A5F1 */
476void reset_maneuver(short ship, short maneuver)
477{
478 g_asShipManeuver[ship] = (enum ShipManeuver)maneuver;
479 g_acShipSequence[ship] = 0;
480 g_asShipCount[ship] = 0;
481}
482
483/* Function start: 0x42A625 */
484void try2reset_maneuver(short obj, short maneuver)
485{
486 if (g_asShipManeuver[obj] != maneuver) {
487 reset_maneuver(obj, maneuver);
488 steady_object(obj);
489 }
490}
491
492/* Function start: 0x42A664 */
493void set_special(short ship, short special)
494{
495
496 if (g_aeSpecialManeuver[ship] <
498 special > g_aeSpecialManeuver[ship])
499 g_aeSpecialManeuver[ship] = special;
500
501 if (g_aeSpecialManeuver[ship] ==
503 (short)alert_flag(ship, 1) != 0)
505}
506
507/* Function start: 0x42A6E8 */
508unsigned int approach_zero_speed(short ship)
509{
510 approach_speed(ship, 0);
511}
512
513/* Function start: 0x42A701 */
514unsigned int approach_min_speed(short obj)
515{
516 approach_speed(obj, 0x500);
517}
518
519/* Function start: 0x42A71D */
520void approach_half_speed(short obj)
521{
523 obj,
525 g_acObjectType[obj]].cruiseVelocity & ~1) << 7);
526}
527
528/* Function start: 0x42A754 */
529unsigned int approach_cruise_speed(short ship)
530{
531 approach_speed(ship,
533 g_acObjectType[ship]].cruiseVelocity << 8);
534}
535
536/* Function start: 0x42A788 */
537unsigned int approach_full_speed(short ship)
538{
539 approach_speed(ship,
540 (int)g_asShipMaximumVelocity[ship] << 8);
541}
542
543/* Function start: 0x42A7AF */
544unsigned int approach_ship_speed(short obj, short other)
545{
546 approach_speed(obj, g_anShipSpeed[other]);
547}
548
549/* Function start: 0x42A7D2 */
550void ComputePointAheadOfObject(short obj, unsigned short distance,
551 FixedVector *point)
552{
554 (int)distance << 8, point);
555 AddFixedVectors(&g_aShipPosition[obj], point, point);
556}
557
558/* Function start: 0x42A823 */
559void ComputePointBehindObject(short obj, unsigned short distance,
560 FixedVector *point)
561{
563 -((int)distance << 8), point);
564 AddFixedVectors(&g_aShipPosition[obj], point, point);
565}
566
567/* Function start: 0x42A876 */
568short close_behind(short range)
569{
570 return g_nTargetRange < range && g_nTargetFacing < -0x32;
571}
572
573void trim_goals(short obj, short amount);
574
575/* Function start: 0x42A8B5 */
576short scan_for_enemy(short obj, unsigned short range)
577{
578 short other;
579 short distance;
580
581 g_nTargetRange = 0;
582 g_nTargetShip = -1;
583 for (other = 0; other < 10; other++) {
584 if (g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
585 g_aeSpecialManeuver[other] !=
587 g_asShipSide[other] != g_asShipSide[obj] &&
588 target_valid(obj, other) != 0) {
589 distance =
591 if (distance < range &&
592 (g_nTargetShip == -1 ||
593 distance < g_nTargetRange)) {
594 g_nTargetShip = other;
595 g_nTargetRange = distance;
596 }
597 }
598 }
599 if (g_nTargetShip != -1) {
603 }
604 return g_nTargetShip;
605}
606
607short distance_from_object(short obj, short other);
608
609/* Function start: 0x42AA0D */
610short any_enemy(short obj, short range)
611{
612 short other;
613
614 g_nTargetShip = -1;
615 for (other = 0; other < 10; other++) {
616 if (g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
617 g_aeSpecialManeuver[other] !=
619 g_asShipSide[obj] != g_asShipSide[other]) {
621 if (g_nTargetRange < range) {
622 g_nTargetShip = other;
623 return 1;
624 }
625 }
626 }
627 return 0;
628}
629
630short ships_within_range(short obj, short other, short range);
631
632/* Function start: 0x42AAD3 */
633/* Nothing in the shipped executable calls this. Like any_enemy, but only
634 * reports whether a live enemy ship is closer than range. */
635short enemy_within_range(short obj, short range)
636{
637 short other;
638 short enemyRange;
639
640 for (other = 0; other < 10; other++) {
641 if (g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
642 g_aeSpecialManeuver[other] !=
644 g_asShipSide[obj] != g_asShipSide[other]) {
645 enemyRange = distance_from_object(obj, other);
646 if (range > enemyRange)
647 return 1;
648 }
649 }
650 return 0;
651}
652
653/* Function start: 0x42AB81 */
654short ships_within_range(short obj, short other, short range)
655{
656 FixedVector delta;
657
659 &g_aShipPosition[other], &delta);
660 return IsVectorWithinRange(&delta, range);
661}
662
663/* Function start: 0x42ABCE */
664short attacker_in_range(short obj, unsigned short range)
665{
666 short other;
667
668 for (other = 0; other < 10; other++) {
669 if (g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
670 g_aeSpecialManeuver[other] !=
672 g_asShipSide[other] != g_asShipSide[obj] &&
673 g_acShipTarget[other] == obj) {
675 if (g_nTargetRange < range) {
676 g_nTargetShip = other;
677 return 1;
678 }
679 }
680 }
681 g_nTargetShip = -1;
682 return 0;
683}
684
685short distance_from_object(short obj, short other);
686
687/* Function start: 0x42ACAF */
688short in_danger(short obj)
689{
690 unsigned short range;
691 short attacker;
692
693 g_nTargetShip = -1;
694 for (attacker = 0; attacker < 10; attacker++) {
695 if (g_aeObjectClass[attacker] >= OBJECT_CLASS_SHIP &&
696 g_aeSpecialManeuver[attacker] !=
698 g_asShipSide[attacker] != g_asShipSide[obj] &&
699 g_acShipTarget[attacker] == obj) {
700 range = (unsigned short)distance_from_object(attacker, obj);
701 if (g_nTargetShip == -1 ||
702 range < g_nTargetRange) {
703 g_nTargetShip = attacker;
704 g_nTargetRange = (short)range;
705 }
706 }
707 }
708 return g_nTargetShip != -1;
709}
710
711/* Function start: 0x42ADB8 */
712short target_within_range(short obj)
713{
714 short target = g_acShipTarget[obj];
715
716 if (unactive(target) != 0)
717 return 0;
718 if (target_valid(obj, target) == 0)
719 return 0;
720 return ships_within_range(obj, target, 7000);
721}
722
723short target_within_range(short obj);
724short unactive(short ship);
725short target_valid(short obj, short target);
726
727/* Function start: 0x42AE32 */
728short build_target_list(short obj, short range)
729{
730 short count;
731 short other;
732 short distance;
733
734 count = 0;
735 for (other = 0; other < 10; other++) {
736 if ((g_aeObjectClass[other] >= OBJECT_CLASS_SHIP &&
737 g_aeSpecialManeuver[other] !=
739 g_asShipSide[other] != g_asShipSide[obj] &&
742 g_asObjectType[other] == 0x13 &&
743 g_acShipTarget[other] == obj)) {
744 distance = distance_from_object(obj, other);
745 if (distance < range) {
746 g_acShipList[count] =
747 (signed char)other;
748 g_asShipListRange[count] = distance;
749 count++;
750 }
751 }
752 }
753 g_acShipList[count] = -1;
754 return count;
755}
756
757/* Function start: 0x42AF60 */
759{
760 short leader = g_asShipWingLeader[obj];
761
762 if (leader != -1 &&
765 g_asShipMissionType[leader];
768 g_aShipMissionSpot[obj] =
769 g_aShipMissionSpot[leader];
770 g_asShipWingLeader[obj] = -1;
771 }
772}
773
774/* Function start: 0x42B00A */
775void inherit_leader(short obj)
776{
777 short leader = g_asShipWingLeader[obj];
778 short other;
779
780 if (leader != -1 && g_aeObjectClass[obj] >= OBJECT_CLASS_SHIP) {
782 g_asShipWingLeader[obj] =
783 g_asShipWingLeader[leader];
784 for (other = 0; other < 10; other++) {
785 if (g_asShipWingLeader[other] == leader)
786 g_asShipWingLeader[other] = obj;
787 }
788 }
789}
790
791/* Function start: 0x42B0B7 */
792short dead_ship(short i)
793{
794 return i == -1 || g_aMissionShips[i].state == 3;
795}
796
797/* Function start: 0x42B0FB */
798short gone_ship(short missionShip)
799{
800 return missionShip == -1 ||
801 g_aMissionShips[missionShip].state == 3 ||
802 g_aMissionShips[missionShip].state == 2;
803}
804
805/* Function start: 0x42B15A */
806/* WC2 passes a margin every caller ignores; the body never reads it. */
807short skill_check(short obj, short margin)
808{
809 if (g_asPilotLevel[obj] < 5 &&
810 RandomBelowOrEqual((short)(g_asPilotLevel[obj] + 4)) == 0)
811 return 0;
812 return 1;
813}
814
815/* Function start: 0x42B1AE */
816short find_ships_sphere(short missionShip)
817{
818 short navIndex;
819 MissionNavPoint *navPoint;
820 short fallback;
821 short shipIndex;
822
823 fallback = -1;
824 navPoint = g_aMissionNavPoints;
825 navIndex = 0;
826 for (; navIndex < MISSION_NAV_POINT_COUNT;
827 navIndex++, navPoint++) {
828 for (shipIndex = 0; shipIndex < MISSION_NAV_POINT_COUNT;
829 shipIndex++) {
830 if (navPoint->missionShips[shipIndex] == missionShip) {
831 if (navPoint->type == 1)
832 return navIndex;
833 else if (fallback == -1)
834 fallback = navIndex;
835 }
836 }
837 }
838 if (fallback != -1) {
839 navIndex = fallback;
840 while (g_aMissionNavPoints[navIndex].type > 1)
841 navIndex--;
842 return navIndex;
843 }
844 return -1;
845}
846
847/* Function start: 0x42B2A7 */
848short locate_ship(short missionShip, FixedVector *point)
849{
850 short navPoint;
851 short obj;
852
853 obj = find_ship_index(missionShip);
854 if (obj != -1) {
855 *point = g_aShipPosition[obj];
856 return 1;
857 }
858 if (dead_ship(missionShip) != 0)
859 return 0;
860 navPoint = find_ships_sphere(missionShip);
861 if (navPoint != -1) {
862 AddFixedVectors(&g_aMissionNavPoints[navPoint].position,
863 &g_aMissionShips[missionShip].position,
864 point);
865 return 1;
866 }
867 zero_vector(point);
868 return 0;
869}
870
871/* Function start: 0x42B38F */
872void get_follow_point(short obj, FixedVector *point)
873{
874 short pathStep;
875 short missionIndex;
876 short shipObj;
877 short navObjective;
878
879 if (g_asShipSide[obj] == SIDE_KILRATHI) {
880 *point = g_aMissionNavPoints[
882 return;
883 }
884 pathStep = (short)g_abShipNavPointIndex[obj];
885 while (++pathStep < MISSION_OBJECTIVE_COUNT) {
886 navObjective = (short)g_abFlightPath[pathStep];
887 switch (g_aMissionObjectives[navObjective].type) {
888 case 0:
889 *point = g_aMissionObjectives[navObjective].position;
890 g_abShipNavPointIndex[obj] = (signed char)pathStep;
891 return;
892 case 1:
893 missionIndex =
894 (short)g_aMissionObjectives[navObjective].index;
895 shipObj = find_ship_index(missionIndex);
896 if (shipObj == -1)
897 *point = g_aMissionNavPoints[missionIndex].position;
898 else
899 *point = g_aShipPosition[shipObj];
900 g_abShipNavPointIndex[obj] = (signed char)pathStep;
901 return;
902 }
903 }
904}
905
906/* Function start: 0x42B524 */
907unsigned int get_first_follow_point(short obj, FixedVector *point)
908{
909 if (g_asShipSide[obj] == SIDE_IMPERIAL)
912 get_follow_point(obj, point);
913}
914
915/* Function start: 0x42B565 */
916short hostile_sphere(short obj, short navPoint)
917{
918 short slot;
919 short missionIndex;
920
921 for (slot = 0; slot < 10; slot++) {
922 missionIndex =
923 g_aMissionNavPoints[navPoint].missionShips[slot];
924 if (missionIndex != -1 &&
925 g_aMissionShips[missionIndex].side !=
926 g_asShipSide[obj])
927 return 1;
928 }
929 return 0;
930}
931
932/* Function start: 0x42B5F7 */
933short abandoned(short obj, short other)
934{
935 short navPoint;
936
937 if ((g_abShipTurn[obj] & 7) != 0 ||
938 g_asShipSide[obj] == SIDE_KILRATHI ||
939 RandomBelowOrEqual(8) != 0)
940 return 0;
941 navPoint = FindNearestNavPoint(obj);
942 if (g_nCurrentNavPoint != navPoint &&
943 hostile_sphere(obj, navPoint) != 0 &&
944 distance_from_object(obj, other) > 10000) {
945 explode(-1, obj);
946 return 1;
947 }
948 return 0;
949}
950
951/* Function start: 0x42B6C5 */
952void engage(short obj, short target, short objective)
953{
954 if (g_aeShipObjective[obj] != objective) {
955 reset_objective(obj, objective);
956 if (g_asPilotLevel[obj] == 5 &&
959 }
960 g_acShipTarget[obj] = target;
961}
962
963short ShipHasTorpedo(short ship);
964short CanShipWeaponDamageTarget(short ship, short target);
965short triumph(short obj);
966
967/* Function start: 0x42B73B */
968short target_valid(short obj, short target)
969{
970 if (target == -1)
971 return 0;
972 if (g_anShipCloakState[target] == 1 &&
973 g_asShipCloakElapsedFrames[target] >= 40)
974 return 0;
975 if (ShipHasTorpedo(obj) == 0 &&
976 CanShipWeaponDamageTarget(obj, target) == 0)
977 return 0;
978 return unactive(target) == 0 &&
979 g_asShipSide[obj] != g_asShipSide[target];
980}
981
982/* Function start: 0x42B80C */
983short triumph(short obj)
984{
985 short result;
986 short objective;
987
988 result = 0;
989 switch (g_asShipMissionType[obj]) {
991 objective = 0;
992 while (g_abFlightPath[objective] != -1) {
993 if (visited((short)g_abFlightPath[objective]) != 0)
994 objective++;
995 else
996 break;
997 }
998 result = 1;
999 break;
1003 result = dead_ship(g_asShipMissionParameter[obj]) == 0;
1004 break;
1006 result = dead_ship(g_asShipMissionParameter[obj]);
1007 break;
1008 }
1009 return result;
1010}
1011
1012/* Function start: 0x42B916 */
1013short find_ratio(short inputMinimum, short inputMaximum,
1014 short input, short outputMinimum,
1015 short outputMaximum)
1016{
1017 if (input < inputMinimum)
1018 return outputMinimum;
1019 if (input > inputMaximum)
1020 return outputMaximum;
1021 return outputMinimum + ((int)(outputMaximum - outputMinimum) *
1022 (int)(input - inputMinimum)) /
1023 (int)(inputMaximum - inputMinimum);
1024}
1025
1026/* Function start: 0x42B985 */
1027short evaluate_damage(short obj)
1028{
1029 short total;
1030 ObjectTypeData *typeData;
1031
1032 total = 0;
1033 typeData = &g_aObjectTypeData[g_acObjectType[obj]];
1035 return 100;
1036 total = (short)(g_aasShipArmor[obj][0] * 23 /
1037 typeData->armorFront + total);
1038 total = (short)(g_aasShipArmor[obj][1] * 27 /
1039 typeData->armorRear + total);
1040 total = (short)(g_aasShipArmor[obj][2] * 12 /
1041 typeData->armorLeft + total);
1042 total = (short)(g_aasShipArmor[obj][3] * 12 /
1043 typeData->armorRight + total);
1044 total = (short)(26 - g_acShipDamage[obj] * 26 /
1045 typeData->damageCapacity + total);
1046 return total;
1047}
1048
1049short g_bKilrathiAceGreetingSent = 0; /* 0x00499bf4 */
1050
1051/* Linker commons defined here. LINK lays a unit's commons out by the
1052 * identifiers' hash keys, so these spellings follow the original addresses. */
1053short g_5_nCollisionCountdownNumber; /* 0x005d2faa */
1054signed char g_acMissionShipStatusFlagsBytes[8]; /* 0x005d2fb0 */
1055short g_bWingmanKilledThisMission; /* 0x005d2fb8 */
1056signed char g_4_acInitialShipKillNumber[8]; /* 0x005d2fc0 */
1057short g_nLastFoundShip; /* 0x005d2fc8 */
void clear_alert(short obj)
Definition logic.c:37
unsigned int approach_full_speed(short ship)
Definition logic.c:537
short real_crash_time(short obj, short other)
Definition logic.c:76
short find_ships_sphere(short missionShip)
Definition logic.c:816
void ComputeVectorDelta(FixedVector *from, FixedVector *to, FixedVector *delta)
Definition geom.c:229
unsigned int approach_zero_speed(short ship)
Definition logic.c:508
short IsVectorWithinRange(FixedVector *vector, short range)
Definition eventmgr.c:2023
void set_alert(short obj, unsigned int bits)
Definition logic.c:31
void set_special(short ship, short special)
Definition logic.c:493
void get_follow_point(short obj, FixedVector *point)
Definition logic.c:872
short MaxShort(short a, short b)
Definition disk.c:36
short enemy_within_range(short obj, short range)
Definition logic.c:635
short detect_collisions(short obj)
Definition logic.c:143
short explode(short attacker, short victim)
Definition ship.c:1915
unsigned int get_first_follow_point(short obj, FixedVector *point)
Definition logic.c:907
short distance_from_point(short obj, const FixedVector *point)
Definition geom.c:538
unsigned int find_squad_center(FixedVector *center)
Definition logic.c:387
void ComputePointAheadOfObject(short obj, unsigned short distance, FixedVector *point)
Definition logic.c:550
short abandoned(short obj, short other)
Definition logic.c:933
long Vector_magnitude(const FixedVector *vector)
Definition eventmgr.c:157
unsigned int alter_objective(short ship, short objective)
Definition logic.c:453
void AddFixedVectors(const FixedVector *left, const FixedVector *right, FixedVector *sum)
Definition geom.c:211
short hostile_sphere(short obj, short navPoint)
Definition logic.c:916
short evaluate_damage(short obj)
Definition logic.c:1027
void init_formation_burst(short obj)
Definition logic.c:403
signed char CanSetNewShipTurnGoal(short ship)
Definition logic.c:303
short unactive(short ship)
Definition logic.c:186
void ScaleFixedVector(FixedVector *vector, int scale, FixedVector *result)
Definition geom.c:237
short are_alive(short obj)
Definition logic.c:194
short FixedToShortSaturating(int value)
Definition geom.c:122
short crash_time(short obj, short other)
Definition logic.c:132
short any_enemy(short obj, short range)
Definition logic.c:610
short find_ratio(short inputMinimum, short inputMaximum, short input, short outputMinimum, short outputMaximum)
Definition logic.c:1013
short scan_for_enemy(short obj, unsigned short range)
Definition logic.c:576
short skill_check(short obj, short margin)
Definition logic.c:807
short CanShipWeaponDamageTarget(short ship, short target)
Definition ship.c:87
unsigned int approach_ship_speed(short obj, short other)
Definition logic.c:544
short distance_from_object(short obj, short other)
Definition geom.c:547
unsigned int approach_speed(short ship, int targetSpeed)
Definition ship.c:682
void try2end_collision_alert(short obj)
Definition logic.c:58
void inherit_leader_mission(short obj)
Definition logic.c:758
short signed_random(short range)
Definition logic.c:19
short visited(short objective)
Definition cockpt.c:1140
void steady_object(short ship)
Definition ship.c:698
void SendKilrathiAceGreetingOnce(short obj)
Definition logic.c:10
short being_tailed(short obj, short other)
Definition logic.c:321
short attacker_in_range(short obj, unsigned short range)
Definition logic.c:664
unsigned int reset_tactic(short ship, short tactic)
Definition logic.c:461
short in_danger(short obj)
Definition logic.c:688
short GetAdaptiveTurnRate(void)
Definition ship.c:137
signed char no_goal(short ship)
Definition logic.c:313
short build_target_list(short obj, short range)
Definition logic.c:728
short triumph(short obj)
Definition logic.c:983
long DivideFixed(int numerator, int denominator)
Definition eventmgr.c:64
void zero_vector(FixedVector *vector)
Definition geom.c:197
unsigned int reset_objective(short ship, short objective)
Definition logic.c:445
short real_velocity(short obj)
Definition ship.c:705
short close_behind()
short ships_within_range(short obj, short other, short range)
Definition logic.c:654
short is_ship_tailing_player_target(short obj)
Definition logic.c:347
short FindNearestNavPoint(short ship)
Definition main.c:1753
void trim_goals(short obj, short amount)
Definition logic.c:201
void engage(short obj, short target, short objective)
Definition logic.c:952
short locate_ship(short missionShip, FixedVector *point)
Definition logic.c:848
unsigned int approach_min_speed(short obj)
Definition logic.c:514
short try2rout(short obj)
Definition logic.c:272
short report_kilrathi_rout(int mode)
Definition logic.c:214
short detect_enemy_tail(short obj)
Definition logic.c:330
short FindMissileTargetingObject(short obj)
Definition logic.c:357
void get_facing_range_from_object(short obj, short other)
Definition geom.c:578
void start_collision_alert(short obj, short other)
Definition logic.c:45
void try2reset_maneuver(short obj, short maneuver)
Definition logic.c:484
short target_within_range(short obj)
Definition logic.c:712
unsigned int approach_cruise_speed(short ship)
Definition logic.c:529
short gone_ship(short missionShip)
Definition logic.c:798
void inherit_leader(short obj)
Definition logic.c:775
void send_message(short obj, signed char message)
Definition cockpt.c:3116
short target_valid(short obj, short target)
Definition logic.c:968
short dead_ship(short missionShip)
Definition logic.c:792
void ProcessEnemyWaveCompletion(void)
Definition ship.c:1514
void divide_vector(FixedVector *vector, int divisor, FixedVector *result)
Definition geom.c:245
void approach_half_speed(short obj)
Definition logic.c:520
short ShipHasTorpedo(short ship)
Definition ship.c:122
void reset_mission_type(short obj, short missionType)
Definition logic.c:426
void ComputePointBehindObject(short obj, unsigned short distance, FixedVector *point)
Definition logic.c:559
void maneuver_complete(short ship)
Definition fl.c:134
short normal_speed(short obj)
Definition logic.c:68
unsigned int alter_tactic(short ship, short tactic)
Definition logic.c:469
short find_ship_index(short missionShip)
Definition logic.c:251
unsigned int change_mission_type(short obj, short missionType)
Definition logic.c:436
void reset_maneuver(short ship, short maneuver)
Definition logic.c:476
short RandomBelowOrEqual(short n)
Definition eventmgr.c:43
void build_squad_list(short leader)
Definition logic.c:370
short alert_flag(short ship, unsigned int bits)
Definition logic.c:25
Shared Win32 declarations, types and library interfaces.
@ MISSION_TYPE_PATROL
Definition game_data.h:122
@ MISSION_TYPE_ESCORT
Definition game_data.h:123
@ MISSION_TYPE_WINGMAN
Definition game_data.h:126
@ MISSION_TYPE_ROUT
Definition game_data.h:127
@ MISSION_TYPE_DEFEND
Definition game_data.h:125
@ MISSION_TYPE_STRIKE
Definition game_data.h:124
@ SIDE_IMPERIAL
Definition game_data.h:175
@ SIDE_KILRATHI
Definition game_data.h:176
@ OBJECTIVE_ENGAGE_ENEMY
Definition game_data.h:145
@ OBJECTIVE_DESTROY_SHIP
Definition game_data.h:143
@ OBJECTIVE_BREAK_FORMATION
Definition game_data.h:148
@ OBJECTIVE_NONE
Definition game_data.h:138
#define MISSION_NAV_POINT_COUNT
Definition game_data.h:1641
#define SHIP_OBJECTIVE_NOT_ALIVE
Definition game_data.h:1646
@ SPECIAL_MANEUVER_LOST_CONTROL
Definition game_data.h:267
@ SPECIAL_MANEUVER_BLOWING_UP
Definition game_data.h:268
@ SPECIAL_MANEUVER_UNKNOWN_9
Definition game_data.h:269
@ SPECIAL_MANEUVER_AFTERBURNER
Definition game_data.h:261
@ SPECIAL_MANEUVER_NONE
Definition game_data.h:259
ShipManeuver
Definition game_data.h:207
@ MANEUVER_HARD_BRAKE
Definition game_data.h:218
@ MANEUVER_NONE
Definition game_data.h:208
#define MISSION_OBJECTIVE_COUNT
Definition game_data.h:1642
@ OBJECT_CLASS_MISSILE
Definition game_data.h:48
@ OBJECT_CLASS_SHIP
Definition game_data.h:49
@ OBJECT_CLASS_CAPITAL_SHIP
Definition game_data.h:50
@ OBJECT_CLASS_FUTURION
Definition game_data.h:38
@ OBJECT_CLASS_ASTEROID
Definition game_data.h:46
@ OBJECT_CLASS_NULL
Definition game_data.h:37
@ TACTIC_NONE
Definition game_data.h:152
HazardField * g_pActiveHazardField
Definition viewrect.c:60
short g_asObjectCollisionRadius[SPACE_OBJECT_COUNT]
Definition viewrect.c:120
short g_asShipAfterburnerTimer[10]
Definition viewrect.c:137
short g_asShipMissionParameter[12]
Definition viewrect.c:164
short g_nCurrentWave
Definition viewrect.c:54
short g_nLastFoundShip
Definition logic.c:1057
short g_nYourWingman
Definition viewrect.c:75
short g_asPilotLevel[12]
Definition viewrect.c:157
short g_nFacingToTarget
Definition viewrect.c:45
signed char g_abFlightPath[MISSION_OBJECTIVE_COUNT]
Definition viewrect.c:68
signed char g_acShipSequence[14]
Definition viewrect.c:176
short g_aeObjectClass[SPACE_OBJECT_COUNT]
Definition viewrect.c:125
signed char g_acShipTarget[16]
Definition viewrect.c:167
short g_asObjectType[SPACE_OBJECT_COUNT]
Definition viewrect.c:124
short g_bKilrathiAceGreetingSent
Definition logic.c:1049
short g_anRollGoal[12]
Definition viewrect.c:132
ObjectTypeData g_aObjectTypeData[OBJECT_DATA_COUNT]
Definition campglob.c:310
MissionNavPoint g_aMissionNavPoints[MISSION_NAV_POINT_COUNT]
Definition hotspot.c:237
unsigned int g_anShipAlertFlags[10]
Definition viewrect.c:172
FixedVector g_aShipForwardVector[SPACE_OBJECT_COUNT]
Definition viewrect.c:107
short g_asObjectScreenX[SPACE_OBJECT_COUNT]
Definition viewrect.c:95
short g_bWingmanKilledThisMission
Definition logic.c:1055
short g_asShipCloakElapsedFrames[10]
Definition viewrect.c:181
short g_aeSpecialManeuver[12]
Definition viewrect.c:141
signed char g_acMissionShipStatusFlagsBytes[8]
Definition logic.c:1054
short g_anYawGoal[12]
Definition viewrect.c:131
signed char g_abShipNavPointIndex[16]
Definition viewrect.c:170
short g_asShipTactic[12]
Definition viewrect.c:168
short g_nTargetFacing
Definition viewrect.c:46
signed char g_acShipList[16]
Definition viewrect.c:195
short g_asShipMaximumVelocity[12]
Definition viewrect.c:171
short g_asShipCount[12]
Definition viewrect.c:177
short g_anPitchGoal[12]
Definition viewrect.c:130
int g_anShipSpeed[SPACE_OBJECT_COUNT]
Definition viewrect.c:116
short g_nTargetShip
Definition viewrect.c:48
short g_asShipWingLeader[12]
Definition viewrect.c:162
short g_5_nCollisionCountdownNumber
Definition logic.c:1053
int g_anShipCloakState[10]
Definition viewrect.c:179
signed char g_4_acInitialShipKillNumber[8]
Definition logic.c:1056
signed char g_cCurrentNavPointIndex
Definition viewrect.c:67
FixedVector g_aShipPosition[SPACE_OBJECT_COUNT]
Definition viewrect.c:108
short g_asShipManeuver[12]
Definition viewrect.c:169
FixedVector g_aShipVelocity[SPACE_OBJECT_COUNT]
Definition viewrect.c:109
short g_asShipMissionIndex[12]
Definition viewrect.c:153
signed char g_acShipAlertSource[12]
Definition viewrect.c:173
signed char g_acShipStress[16]
Definition viewrect.c:187
signed char g_abShipTurn[16]
Definition viewrect.c:175
short g_aeShipObjective[12]
Definition viewrect.c:166
FixedVector g_aShipDestination[10]
Definition viewrect.c:128
MissionObjective g_aMissionObjectives[MISSION_OBJECTIVE_COUNT]
Definition viewrect.c:69
short g_asShipListRange[16]
Definition viewrect.c:196
short g_nTargetRange
Definition viewrect.c:47
MissionShipRecord g_aMissionShips[MISSION_SHIP_COUNT]
Definition hotspot.c:240
short g_aasShipArmor[10][4]
Definition viewrect.c:135
signed char g_acShipDamage[16]
Definition viewrect.c:148
short g_asShipMissionType[12]
Definition viewrect.c:163
FixedVector g_aShipMissionSpot[20]
Definition viewrect.c:165
short g_asShipSide[12]
Definition viewrect.c:139
signed char g_acObjectType[SPACE_OBJECT_COUNT]
Definition viewrect.c:101
short g_nCurrentNavPoint
Definition viewrect.c:53
short g_asShipAlertCountdown[12]
Definition viewrect.c:174
FixedVector position
Definition game_data.h:1327
short missionShips[10]
Definition game_data.h:1336
signed char type
Definition game_data.h:1326
FixedVector position
Definition game_data.h:1422
signed char state
Definition game_data.h:1380
short damageCapacity
Definition game_data.h:375