2 * $Logfile: /Freespace2/code/Object/CollideWeaponWeapon.cpp $
7 * Routines to detect collisions and do physics, damage, etc for weapons and weapons
10 * Revision 1.1 2002/05/03 03:28:10 root
14 * 5 8/27/99 9:32a Andsager
15 * Debug info for shooting down bombs
17 * 4 8/27/99 1:34a Andsager
18 * Modify damage by shockwaves for BIG|HUGE ships. Modify shockwave damge
19 * when weapon blows up.
21 * 3 10/16/98 1:22p Andsager
22 * clean up header files
24 * 2 10/07/98 10:53a Dave
27 * 1 10/07/98 10:50a Dave
29 * 8 5/22/98 11:00a Mike
32 * 7 4/15/98 11:30p Mike
33 * Make bombs not drop for first half second and increase arm time from
36 * 6 3/05/98 5:48p Lawrance
37 * Double radius of bombs when doing weapon-weapon collisions
39 * 5 2/22/98 12:19p John
40 * Externalized some strings
42 * 4 2/14/98 3:38p Mike
43 * Make bombs have arm time, drop for 1/2 second, have hull_strength.
44 * Make them not fired until closer to target.
46 * 3 10/24/97 2:14p Adam
47 * removed nprintf() call whose string is too long
49 * 2 9/17/97 5:12p John
50 * Restructured collision routines. Probably broke a lot of stuff.
52 * 1 9/17/97 2:14p John
59 #include "objcollide.h"
60 #include "freespace.h"
66 char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
70 #define BOMB_ARM_TIME 1.5f
72 // Checks weapon-weapon collisions. pair->a and pair->b are weapons.
73 // Returns 1 if all future collisions between these can be ignored
74 int collide_weapon_weapon( obj_pair * pair )
76 float A_radius, B_radius;
80 Assert( A->type == OBJ_WEAPON );
81 Assert( B->type == OBJ_WEAPON );
83 // Don't allow ship to shoot down its own missile.
84 if (A->parent_sig == B->parent_sig)
87 // Only shoot down teammate's missile if not traveling in nearly same direction.
88 if (Weapons[A->instance].team == Weapons[B->instance].team)
89 if (vm_vec_dot(&A->orient.fvec, &B->orient.fvec) > 0.7f)
92 // Ignore collisions involving a bomb if the bomb is not yet armed.
94 weapon_info *wipA, *wipB;
96 wpA = &Weapons[A->instance];
97 wpB = &Weapons[B->instance];
98 wipA = &Weapon_info[wpA->weapon_info_index];
99 wipB = &Weapon_info[wpB->weapon_info_index];
101 A_radius = A->radius;
102 B_radius = B->radius;
104 if (wipA->wi_flags & WIF_BOMB) {
105 A_radius *= 2; // Makes bombs easier to hit
106 if (wipA->lifetime - wpA->lifeleft < BOMB_ARM_TIME)
110 if (wipB->wi_flags & WIF_BOMB) {
111 B_radius *= 2; // Makes bombs easier to hit
112 if (wipB->lifetime - wpB->lifeleft < BOMB_ARM_TIME)
116 // Rats, do collision detection.
117 if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
120 sap = &Ships[Objects[A->parent].instance];
121 sbp = &Ships[Objects[B->parent].instance];
122 // MWA -- commented out next line because it was too long for output window on occation.
123 // Yes -- I should fix the output window, but I don't have time to do it now.
124 //nprintf(("AI", "[%s] %s's missile %i shot down by [%s] %s's laser %i\n", lTeamNames[sbp->team], sbp->ship_name, B->instance, lTeamNames[sap->team], sap->ship_name, A->instance));
125 if (wipA->wi_flags & WIF_BOMB) {
126 if (wipB->wi_flags & WIF_BOMB) { // Two bombs collide, detonate both.
127 Weapons[A->instance].lifeleft = 0.01f;
128 Weapons[B->instance].lifeleft = 0.01f;
129 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
130 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
132 A->hull_strength -= wipB->damage;
133 if (A->hull_strength < 0.0f) {
134 Weapons[A->instance].lifeleft = 0.01f;
135 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
138 } else if (wipB->wi_flags & WIF_BOMB) {
139 B->hull_strength -= wipA->damage;
140 if (B->hull_strength < 0.0f) {
141 Weapons[B->instance].lifeleft = 0.01f;
142 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
147 if (Weapons[A->instance].lifeleft == 0.01f) {
148 dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
149 nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipA->name, dist, wipA->inner_radius, wipA->outer_radius));
151 if (Weapons[B->instance].lifeleft == 0.01f) {
152 dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
153 nprintf(("AI", "Frame %i: Weapon %s shot down. Dist: %.1f, inner: %.0f, outer: %.0f\n", Framecount, wipB->name, dist, wipB->inner_radius, wipB->outer_radius));