]> icculus.org git repositories - taylor/freespace2.git/blob - src/object/collideweaponweapon.cpp
Initial revision
[taylor/freespace2.git] / src / object / collideweaponweapon.cpp
1 /*
2  * $Logfile: /Freespace2/code/Object/CollideWeaponWeapon.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Routines to detect collisions and do physics, damage, etc for weapons and weapons
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:10  root
11  * Initial revision
12  *
13  * 
14  * 5     8/27/99 9:32a Andsager
15  * Debug info for shooting down bombs
16  * 
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.
20  * 
21  * 3     10/16/98 1:22p Andsager
22  * clean up header files
23  * 
24  * 2     10/07/98 10:53a Dave
25  * Initial checkin.
26  * 
27  * 1     10/07/98 10:50a Dave
28  * 
29  * 8     5/22/98 11:00a Mike
30  * Balance sm3-09a.
31  * 
32  * 7     4/15/98 11:30p Mike
33  * Make bombs not drop for first half second and increase arm time from
34  * 1.0 to 1.5 seconds.
35  * 
36  * 6     3/05/98 5:48p Lawrance
37  * Double radius of bombs when doing weapon-weapon collisions
38  * 
39  * 5     2/22/98 12:19p John
40  * Externalized some strings
41  * 
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.
45  * 
46  * 3     10/24/97 2:14p Adam
47  * removed nprintf() call whose string is too long
48  * 
49  * 2     9/17/97 5:12p John
50  * Restructured collision routines.  Probably broke a lot of stuff.
51  * 
52  * 1     9/17/97 2:14p John
53  * Initial revision
54  *
55  * $NoKeywords: $
56  */
57
58
59 #include "objcollide.h"
60 #include "freespace.h"
61 #include "object.h"
62 #include "weapon.h"
63
64 #ifndef NDEBUG
65 //XSTR:OFF
66 char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
67 //XSTR:ON
68 #endif
69
70 #define BOMB_ARM_TIME   1.5f
71
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 )
75 {
76         float A_radius, B_radius;
77         object *A = pair->a;
78         object *B = pair->b;
79
80         Assert( A->type == OBJ_WEAPON );
81         Assert( B->type == OBJ_WEAPON );
82         
83         //      Don't allow ship to shoot down its own missile.
84         if (A->parent_sig == B->parent_sig)
85                 return 1;
86
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)
90                         return 1;
91
92         //      Ignore collisions involving a bomb if the bomb is not yet armed.
93         weapon  *wpA, *wpB;
94         weapon_info     *wipA, *wipB;
95
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];
100
101         A_radius = A->radius;
102         B_radius = B->radius;
103
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)
107                         return 0;
108         }
109
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)
113                         return 0;
114         }
115
116         //      Rats, do collision detection.
117         if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
118                 ship    *sap, *sbp;
119
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;
131                         } else {
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;
136                                 }
137                         }
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;
143                         }
144                 }
145
146                 float dist = 0.0f;
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));
150                 }
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));
154                 }
155                 return 1;
156         }
157
158         return 0;
159 }
160