2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Object/CollideWeaponWeapon.cpp $
15 * Routines to detect collisions and do physics, damage, etc for weapons and weapons
18 * Revision 1.2 2002/06/09 04:41:24 relnev
19 * added copyright header
21 * Revision 1.1.1.1 2002/05/03 03:28:10 root
25 * 5 8/27/99 9:32a Andsager
26 * Debug info for shooting down bombs
28 * 4 8/27/99 1:34a Andsager
29 * Modify damage by shockwaves for BIG|HUGE ships. Modify shockwave damge
30 * when weapon blows up.
32 * 3 10/16/98 1:22p Andsager
33 * clean up header files
35 * 2 10/07/98 10:53a Dave
38 * 1 10/07/98 10:50a Dave
40 * 8 5/22/98 11:00a Mike
43 * 7 4/15/98 11:30p Mike
44 * Make bombs not drop for first half second and increase arm time from
47 * 6 3/05/98 5:48p Lawrance
48 * Double radius of bombs when doing weapon-weapon collisions
50 * 5 2/22/98 12:19p John
51 * Externalized some strings
53 * 4 2/14/98 3:38p Mike
54 * Make bombs have arm time, drop for 1/2 second, have hull_strength.
55 * Make them not fired until closer to target.
57 * 3 10/24/97 2:14p Adam
58 * removed nprintf() call whose string is too long
60 * 2 9/17/97 5:12p John
61 * Restructured collision routines. Probably broke a lot of stuff.
63 * 1 9/17/97 2:14p John
70 #include "objcollide.h"
71 #include "freespace.h"
77 char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
81 #define BOMB_ARM_TIME 1.5f
83 // Checks weapon-weapon collisions. pair->a and pair->b are weapons.
84 // Returns 1 if all future collisions between these can be ignored
85 int collide_weapon_weapon( obj_pair * pair )
87 float A_radius, B_radius;
91 Assert( A->type == OBJ_WEAPON );
92 Assert( B->type == OBJ_WEAPON );
94 // Don't allow ship to shoot down its own missile.
95 if (A->parent_sig == B->parent_sig)
98 // Only shoot down teammate's missile if not traveling in nearly same direction.
99 if (Weapons[A->instance].team == Weapons[B->instance].team)
100 if (vm_vec_dot(&A->orient.fvec, &B->orient.fvec) > 0.7f)
103 // Ignore collisions involving a bomb if the bomb is not yet armed.
105 weapon_info *wipA, *wipB;
107 wpA = &Weapons[A->instance];
108 wpB = &Weapons[B->instance];
109 wipA = &Weapon_info[wpA->weapon_info_index];
110 wipB = &Weapon_info[wpB->weapon_info_index];
112 A_radius = A->radius;
113 B_radius = B->radius;
115 if (wipA->wi_flags & WIF_BOMB) {
116 A_radius *= 2; // Makes bombs easier to hit
117 if (wipA->lifetime - wpA->lifeleft < BOMB_ARM_TIME)
121 if (wipB->wi_flags & WIF_BOMB) {
122 B_radius *= 2; // Makes bombs easier to hit
123 if (wipB->lifetime - wpB->lifeleft < BOMB_ARM_TIME)
127 // Rats, do collision detection.
128 if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
131 sap = &Ships[Objects[A->parent].instance];
132 sbp = &Ships[Objects[B->parent].instance];
133 // MWA -- commented out next line because it was too long for output window on occation.
134 // Yes -- I should fix the output window, but I don't have time to do it now.
135 //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));
136 if (wipA->wi_flags & WIF_BOMB) {
137 if (wipB->wi_flags & WIF_BOMB) { // Two bombs collide, detonate both.
138 Weapons[A->instance].lifeleft = 0.01f;
139 Weapons[B->instance].lifeleft = 0.01f;
140 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
141 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
143 A->hull_strength -= wipB->damage;
144 if (A->hull_strength < 0.0f) {
145 Weapons[A->instance].lifeleft = 0.01f;
146 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
149 } else if (wipB->wi_flags & WIF_BOMB) {
150 B->hull_strength -= wipA->damage;
151 if (B->hull_strength < 0.0f) {
152 Weapons[B->instance].lifeleft = 0.01f;
153 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
158 if (Weapons[A->instance].lifeleft == 0.01f) {
159 dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
160 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));
162 if (Weapons[B->instance].lifeleft == 0.01f) {
163 dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
164 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));