]> icculus.org git repositories - taylor/freespace2.git/blob - src/object/collideweaponweapon.cpp
ryan's struct patch for gcc 2.95
[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.3  2002/06/17 06:33:10  relnev
19  * ryan's struct patch for gcc 2.95
20  *
21  * Revision 1.2  2002/06/09 04:41:24  relnev
22  * added copyright header
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:10  root
25  * Initial import.
26  *
27  * 
28  * 5     8/27/99 9:32a Andsager
29  * Debug info for shooting down bombs
30  * 
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.
34  * 
35  * 3     10/16/98 1:22p Andsager
36  * clean up header files
37  * 
38  * 2     10/07/98 10:53a Dave
39  * Initial checkin.
40  * 
41  * 1     10/07/98 10:50a Dave
42  * 
43  * 8     5/22/98 11:00a Mike
44  * Balance sm3-09a.
45  * 
46  * 7     4/15/98 11:30p Mike
47  * Make bombs not drop for first half second and increase arm time from
48  * 1.0 to 1.5 seconds.
49  * 
50  * 6     3/05/98 5:48p Lawrance
51  * Double radius of bombs when doing weapon-weapon collisions
52  * 
53  * 5     2/22/98 12:19p John
54  * Externalized some strings
55  * 
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.
59  * 
60  * 3     10/24/97 2:14p Adam
61  * removed nprintf() call whose string is too long
62  * 
63  * 2     9/17/97 5:12p John
64  * Restructured collision routines.  Probably broke a lot of stuff.
65  * 
66  * 1     9/17/97 2:14p John
67  * Initial revision
68  *
69  * $NoKeywords: $
70  */
71
72
73 #include "objcollide.h"
74 #include "freespace.h"
75 #include "object.h"
76 #include "weapon.h"
77
78 #ifndef NDEBUG
79 //XSTR:OFF
80 char *lTeamNames[3] = { "Hostile", "Friendly", "Unknown" };
81 //XSTR:ON
82 #endif
83
84 #define BOMB_ARM_TIME   1.5f
85
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 )
89 {
90         float A_radius, B_radius;
91         object *A = pair->a;
92         object *B = pair->b;
93
94         Assert( A->type == OBJ_WEAPON );
95         Assert( B->type == OBJ_WEAPON );
96         
97         //      Don't allow ship to shoot down its own missile.
98         if (A->parent_sig == B->parent_sig)
99                 return 1;
100
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)
104                         return 1;
105
106         //      Ignore collisions involving a bomb if the bomb is not yet armed.
107         weapon  *wpA, *wpB;
108         weapon_info     *wipA, *wipB;
109
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];
114
115         A_radius = A->radius;
116         B_radius = B->radius;
117
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)
121                         return 0;
122         }
123
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)
127                         return 0;
128         }
129
130         //      Rats, do collision detection.
131         if (collide_subdivide(&A->last_pos, &A->pos, A_radius, &B->last_pos, &B->pos, B_radius)) {
132                 ship    *sap, *sbp;
133
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;
145                         } else {
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;
150                                 }
151                         }
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;
157                         }
158                 }
159
160                 float dist = 0.0f;
161                 if (Weapons[A->instance].lifeleft == 0.01f) {
162                         dist = vm_vec_dist_quick(&A->pos, &wpA->homing_pos);
163                         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));
164                 }
165                 if (Weapons[B->instance].lifeleft == 0.01f) {
166                         dist = vm_vec_dist_quick(&A->pos, &wpB->homing_pos);
167                         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));
168                 }
169                 return 1;
170         }
171
172         return 0;
173 }
174