]> icculus.org git repositories - taylor/freespace2.git/blob - src/object/collideweaponweapon.cpp
added copyright header
[taylor/freespace2.git] / src / object / collideweaponweapon.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
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
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Object/CollideWeaponWeapon.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Routines to detect collisions and do physics, damage, etc for weapons and weapons
16  *
17  * $Log$
18  * Revision 1.2  2002/06/09 04:41:24  relnev
19  * added copyright header
20  *
21  * Revision 1.1.1.1  2002/05/03 03:28:10  root
22  * Initial import.
23  *
24  * 
25  * 5     8/27/99 9:32a Andsager
26  * Debug info for shooting down bombs
27  * 
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.
31  * 
32  * 3     10/16/98 1:22p Andsager
33  * clean up header files
34  * 
35  * 2     10/07/98 10:53a Dave
36  * Initial checkin.
37  * 
38  * 1     10/07/98 10:50a Dave
39  * 
40  * 8     5/22/98 11:00a Mike
41  * Balance sm3-09a.
42  * 
43  * 7     4/15/98 11:30p Mike
44  * Make bombs not drop for first half second and increase arm time from
45  * 1.0 to 1.5 seconds.
46  * 
47  * 6     3/05/98 5:48p Lawrance
48  * Double radius of bombs when doing weapon-weapon collisions
49  * 
50  * 5     2/22/98 12:19p John
51  * Externalized some strings
52  * 
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.
56  * 
57  * 3     10/24/97 2:14p Adam
58  * removed nprintf() call whose string is too long
59  * 
60  * 2     9/17/97 5:12p John
61  * Restructured collision routines.  Probably broke a lot of stuff.
62  * 
63  * 1     9/17/97 2:14p John
64  * Initial revision
65  *
66  * $NoKeywords: $
67  */
68
69
70 #include "objcollide.h"
71 #include "freespace.h"
72 #include "object.h"
73 #include "weapon.h"
74
75 #ifndef NDEBUG
76 //XSTR:OFF
77 char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
78 //XSTR:ON
79 #endif
80
81 #define BOMB_ARM_TIME   1.5f
82
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 )
86 {
87         float A_radius, B_radius;
88         object *A = pair->a;
89         object *B = pair->b;
90
91         Assert( A->type == OBJ_WEAPON );
92         Assert( B->type == OBJ_WEAPON );
93         
94         //      Don't allow ship to shoot down its own missile.
95         if (A->parent_sig == B->parent_sig)
96                 return 1;
97
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)
101                         return 1;
102
103         //      Ignore collisions involving a bomb if the bomb is not yet armed.
104         weapon  *wpA, *wpB;
105         weapon_info     *wipA, *wipB;
106
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];
111
112         A_radius = A->radius;
113         B_radius = B->radius;
114
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)
118                         return 0;
119         }
120
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)
124                         return 0;
125         }
126
127         //      Rats, do collision detection.
128         if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
129                 ship    *sap, *sbp;
130
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;
142                         } else {
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;
147                                 }
148                         }
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;
154                         }
155                 }
156
157                 float dist = 0.0f;
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));
161                 }
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));
165                 }
166                 return 1;
167         }
168
169         return 0;
170 }
171