]> icculus.org git repositories - taylor/freespace2.git/blob - src/ship/shipcontrails.cpp
Initial revision
[taylor/freespace2.git] / src / ship / shipcontrails.cpp
1 /*
2  * $Logfile: /Freespace2/code/Ship/ShipContrails.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * all sorts of cool stuff about ships
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:10  root
11  * Initial revision
12  *
13  * 
14  * 5     4/25/99 3:02p Dave
15  * Build defines for the E3 build.
16  * 
17  * 4     4/20/99 6:39p Dave
18  * Almost done with artillery targeting. Added support for downloading
19  * images on the PXO screen.
20  * 
21  * 3     4/12/99 11:03p Dave
22  * Removed contrails and muzzle flashes from MULTIPLAYER_BETA builds.
23  * 
24  * 2     11/14/98 5:33p Dave
25  * Lots of nebula work. Put in ship contrails.
26  * 
27  * 1     11/14/98 3:40p Dave
28  * 
29  * 1     11/13/98 3:28p Dave
30  * 
31  * 
32  * $NoKeywords: $
33  */
34
35 #include "shipcontrails.h"
36 #include "object.h"
37 #include "ship.h"
38 #include "linklist.h"
39 #include "3d.h"
40 #include "alphacolors.h"
41 #include "trails.h"
42 #include "bmpman.h"
43 #include "missionparse.h"
44
45 // ----------------------------------------------------------------------------------------------
46 // CONTRAIL DEFINES/VARS
47 //
48
49 // ----------------------------------------------------------------------------------------------
50 // CONTRAIL FORWARD DECLARATIONS
51 //
52
53 // if the object is below the limit for contrails
54 int ct_below_limit(object *objp);
55
56 // if an object has active contrails
57 int ct_has_contrails(ship *shipp);
58
59 // update active contrails - moving existing ones, adding new ones where necessary
60 void ct_update_contrails(ship *shipp);
61
62 // create new contrails
63 void ct_create_contrails(ship *shipp);
64
65 // ----------------------------------------------------------------------------------------------
66 // CONTRAIL FUNCTIONS
67 //
68
69 // call during level initialization
70 void ct_level_init()
71 {       
72 }
73
74 // call during level shutdown
75 void ct_level_close()
76 {       
77 }
78
79 // call when a ship is created to initialize its contrail stuff
80 void ct_ship_create(ship *shipp)
81 {
82         int idx;
83         Assert(shipp != NULL);
84
85         // null out the ct indices for this guy
86         for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
87                 shipp->trail_num[idx] = (short)-1;
88         }
89 }
90
91 // call when a ship is deleted to free up its contrail stuff
92 void ct_ship_delete(ship *shipp)
93 {
94         int idx;                
95
96         Assert(shipp != NULL);
97         // free up any contrails this guy may have had
98         for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
99                 if(shipp->trail_num[idx] >= 0){
100                         trail_object_died(shipp->trail_num[idx]);
101                         shipp->trail_num[idx] = (short)-1;
102                 }
103         }
104 }
105
106 // call each frame for processing a ship's contrails
107 void ct_ship_process(ship *shipp)
108 {
109 #ifdef MULTIPLAYER_BETA_BUILD
110         return;
111 #else
112         int idx;                
113         object *objp;
114
115         Assert(shipp != NULL);
116         Assert(shipp->objnum >= 0);
117         objp = &Objects[shipp->objnum];
118
119         // if not a fullneb mission - do nothing
120         if(!(The_mission.flags & MISSION_FLAG_FULLNEB)){
121                 return;
122         }
123
124         // if this is not a ship, we don't care
125         if((objp->type != OBJ_SHIP) || (Ship_info[Ships[objp->instance].ship_info_index].ct_count <= 0)){
126                 return;
127         }
128
129         Assert(objp->instance >= 0);
130         shipp = &Ships[objp->instance];
131
132         // if the object is below the critical limit
133         if(ct_below_limit(objp)){
134                 // kill any active trails he has
135                 for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
136                         if(shipp->trail_num[idx] >= 0){
137                                 trail_object_died(shipp->trail_num[idx]);
138                                 shipp->trail_num[idx] = (short)-1;
139                         }
140                 }
141
142                 // were done
143                 return;
144         }       
145
146         // if the object already has contrails
147         if(ct_has_contrails(shipp)){
148                 ct_update_contrails(shipp);
149         }
150         // otherwise add new ones
151         else {
152                 ct_create_contrails(shipp);
153         }
154 #endif
155 }
156
157 // ----------------------------------------------------------------------------------------------
158 // CONTRAIL FORWARD DEFINITIONS - test stuff
159 //
160
161 // if the object is below the limit for contrails
162 int ct_below_limit(object *objp)
163 {
164         return objp->phys_info.fspeed < 45.0f;
165 }
166
167 // if a ship has active contrails
168 int ct_has_contrails(ship *shipp)
169 {
170         int idx;
171
172         for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
173                 if(shipp->trail_num[idx] >= 0){
174                         return 1;
175                 }
176         }
177
178         // no contrails
179         return 0;
180 }
181
182 // update active contrails - moving existing ones, adding new ones where necessary
183 void ct_update_contrails(ship *shipp)
184 {
185 #ifdef MULTIPLAYER_BETA_BUILD
186         return;
187 #else
188         vector v1;
189         matrix m;
190         int idx;
191         ship_info *sip;
192         object *objp;
193
194         // if not a fullneb mission - do nothing
195         if(!(The_mission.flags & MISSION_FLAG_FULLNEB)){
196                 return;
197         }
198
199         // get object and ship info
200         Assert(shipp != NULL);
201         Assert(shipp->objnum >= 0);
202         Assert(shipp->ship_info_index >= 0);
203         objp = &Objects[shipp->objnum];
204         sip = &Ship_info[shipp->ship_info_index];
205
206         // get the inverse rotation matrix
207         vm_copy_transpose_matrix(&m, &objp->orient);
208
209         // process each contrail        
210         for(idx=0; idx<MAX_SHIP_CONTRAILS; idx++){
211                 // if this is a valid contrail
212                 if(shipp->trail_num[idx] >= 0){ 
213                         // get the point for the contrail
214                         vm_vec_rotate(&v1, &sip->ct_info[idx].pt, &m);
215                         vm_vec_add2(&v1, &objp->pos);
216                 
217                         // if the spew stamp has elapsed
218                         if(trail_stamp_elapsed(shipp->trail_num[idx])){ 
219                                 trail_add_segment(shipp->trail_num[idx], &v1);
220                                 trail_set_stamp(shipp->trail_num[idx]);
221                         } else {
222                                 trail_set_segment(shipp->trail_num[idx], &v1);
223                         }                       
224                 }
225         }       
226 #endif
227 }
228
229 // create new contrails
230 void ct_create_contrails(ship *shipp)
231 {
232 #ifdef MULTIPLAYER_BETA_BUILD
233         return;
234 #else
235         vector v1;
236         int idx;
237         matrix m;
238         ship_info *sip;
239         object *objp;
240
241         // if not a fullneb mission - do nothing
242         if(!(The_mission.flags & MISSION_FLAG_FULLNEB)){
243                 return;
244         }
245
246         // get object and ship info
247         Assert(shipp != NULL);
248         Assert(shipp->objnum >= 0);
249         Assert(shipp->ship_info_index >= 0);
250         objp = &Objects[shipp->objnum];
251         sip = &Ship_info[shipp->ship_info_index];
252
253         // get the inverse rotation matrix
254         vm_copy_transpose_matrix(&m, &objp->orient);
255
256         for(idx=0; idx<sip->ct_count; idx++){
257                 shipp->trail_num[idx] = (short)trail_create(sip->ct_info[idx]); 
258
259                 // add the point                
260                 vm_vec_rotate(&v1, &sip->ct_info[idx].pt, &m);
261                 vm_vec_add2(&v1, &objp->pos);
262                 trail_add_segment(shipp->trail_num[idx], &v1);
263                 trail_add_segment(shipp->trail_num[idx], &v1);
264         }
265 #endif
266 }