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.3 2002/06/17 06:33:10 relnev
19 * ryan's struct patch for gcc 2.95
21 * Revision 1.2 2002/06/09 04:41:24 relnev
22 * added copyright header
24 * Revision 1.1.1.1 2002/05/03 03:28:10 root
28 * 5 8/27/99 9:32a Andsager
29 * Debug info for shooting down bombs
31 * 4 8/27/99 1:34a Andsager
32 * Modify damage by shockwaves for BIG|HUGE ships. Modify shockwave damge
33 * when weapon blows up.
35 * 3 10/16/98 1:22p Andsager
36 * clean up header files
38 * 2 10/07/98 10:53a Dave
41 * 1 10/07/98 10:50a Dave
43 * 8 5/22/98 11:00a Mike
46 * 7 4/15/98 11:30p Mike
47 * Make bombs not drop for first half second and increase arm time from
50 * 6 3/05/98 5:48p Lawrance
51 * Double radius of bombs when doing weapon-weapon collisions
53 * 5 2/22/98 12:19p John
54 * Externalized some strings
56 * 4 2/14/98 3:38p Mike
57 * Make bombs have arm time, drop for 1/2 second, have hull_strength.
58 * Make them not fired until closer to target.
60 * 3 10/24/97 2:14p Adam
61 * removed nprintf() call whose string is too long
63 * 2 9/17/97 5:12p John
64 * Restructured collision routines. Probably broke a lot of stuff.
66 * 1 9/17/97 2:14p John
73 #include "objcollide.h"
74 #include "freespace.h"
80 const char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
84 #define BOMB_ARM_TIME 1.5f
86 // Checks weapon-weapon collisions. pair->a and pair->b are weapons.
87 // Returns 1 if all future collisions between these can be ignored
88 int collide_weapon_weapon( obj_pair * pair )
90 float A_radius, B_radius;
94 SDL_assert( A->type == OBJ_WEAPON );
95 SDL_assert( B->type == OBJ_WEAPON );
97 // Don't allow ship to shoot down its own missile.
98 if (A->parent_sig == B->parent_sig)
101 // Only shoot down teammate's missile if not traveling in nearly same direction.
102 if (Weapons[A->instance].team == Weapons[B->instance].team)
103 if (vm_vec_dot(&A->orient.v.fvec, &B->orient.v.fvec) > 0.7f)
106 // Ignore collisions involving a bomb if the bomb is not yet armed.
108 weapon_info *wipA, *wipB;
110 wpA = &Weapons[A->instance];
111 wpB = &Weapons[B->instance];
112 wipA = &Weapon_info[wpA->weapon_info_index];
113 wipB = &Weapon_info[wpB->weapon_info_index];
115 A_radius = A->radius;
116 B_radius = B->radius;
118 if (wipA->wi_flags & WIF_BOMB) {
119 A_radius *= 2; // Makes bombs easier to hit
120 if (wipA->lifetime - wpA->lifeleft < BOMB_ARM_TIME)
124 if (wipB->wi_flags & WIF_BOMB) {
125 B_radius *= 2; // Makes bombs easier to hit
126 if (wipB->lifetime - wpB->lifeleft < BOMB_ARM_TIME)
130 // Rats, do collision detection.
131 if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
134 //sap = &Ships[Objects[A->parent].instance];
135 //sbp = &Ships[Objects[B->parent].instance];
136 // MWA -- commented out next line because it was too long for output window on occation.
137 // Yes -- I should fix the output window, but I don't have time to do it now.
138 //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));
139 if (wipA->wi_flags & WIF_BOMB) {
140 if (wipB->wi_flags & WIF_BOMB) { // Two bombs collide, detonate both.
141 Weapons[A->instance].lifeleft = 0.01f;
142 Weapons[B->instance].lifeleft = 0.01f;
143 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
144 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
146 A->hull_strength -= wipB->damage;
147 if (A->hull_strength < 0.0f) {
148 Weapons[A->instance].lifeleft = 0.01f;
149 Weapons[A->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
152 } else if (wipB->wi_flags & WIF_BOMB) {
153 B->hull_strength -= wipA->damage;
154 if (B->hull_strength < 0.0f) {
155 Weapons[B->instance].lifeleft = 0.01f;
156 Weapons[B->instance].weapon_flags |= WF_DESTROYED_BY_WEAPON;
162 if (Weapons[A->instance].lifeleft == 0.01f) {
163 dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
164 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));
166 if (Weapons[B->instance].lifeleft == 0.01f) {
167 dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
168 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));