]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/multi_sw.cpp
basic PXO cross-platform network compatibility
[taylor/freespace2.git] / src / network / multi_sw.cpp
1 /*
2  * Copyright (C) Volition, Inc. 2005.  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 the 
6  * source.
7  *
8 */
9
10 /*
11  * $Logfile: /Freespace2/code/Network/multi_sw.cpp $
12  * $Revision: 10 $
13  * $Date: 9/13/99 11:30a $
14  * $Author: Dave $
15  *
16  * $Log: /Freespace2/code/Network/multi_sw.cpp $  
17  * 
18  * 10    9/13/99 11:30a Dave
19  * Added checkboxes and functionality for disabling PXO banners as well as
20  * disabling d3d zbuffer biasing.
21  * 
22  * 9     9/04/99 8:00p Dave
23  * Fixed up 1024 and 32 bit movie support.
24  * 
25  * 8     8/25/99 4:38p Dave
26  * Updated PXO stuff. Make squad war report stuff much more nicely.
27  * 
28  * 7     4/09/99 2:21p Dave
29  * Multiplayer beta stuff. CD checking.
30  * 
31  * 6     2/24/99 2:25p Dave
32  * Fixed up chatbox bugs. Made squad war reporting better. Fixed a respawn
33  * bug for dogfight more.
34  * 
35  * 5     2/19/99 2:55p Dave
36  * Temporary checking to report the winner of a squad war match.
37  * 
38  * 4     2/17/99 2:11p Dave
39  * First full run of squad war. All freespace and tracker side stuff
40  * works.
41  * 
42  * 3     2/12/99 6:16p Dave
43  * Pre-mission Squad War code is 95% done.
44  * 
45  * 2     2/11/99 3:08p Dave
46  * PXO refresh button. Very preliminary squad war support.
47  *  
48  *  
49  * $NoKeywords: $
50  */
51
52
53 #include "systemvars.h"
54 #include "localize.h"
55 #include "multi.h"
56 #include "popup.h"
57 #include "ptrack.h"
58 #include "multi_fstracker.h"
59 #include "multimsgs.h"
60 #include "multi_team.h"
61 #include "multi_sw.h"
62 #include "multi_pmsg.h"
63 #include "multiutil.h"
64 #include "freespace.h"
65
66 // ------------------------------------------------------------------------------------
67 // MULTIPLAYER SQUAD WAR DEFINES/VARS
68 //
69
70 // global request info
71 squad_war_request       Multi_sw_request;
72
73 // global result info
74 squad_war_result Multi_sw_result;
75
76 // set on the host in response to a standalone sw query, -1 == waiting, 0 == fail, 1 == success
77 int Multi_sw_std_query = -1;
78
79 // match code
80 char Multi_sw_match_code[MATCH_CODE_LEN];
81
82 // reply from a standalone on a bad response
83 char Multi_sw_bad_reply[MAX_SQUAD_RESPONSE_LEN+1] = "";
84
85 // team scores
86 extern int Multi_team0_score;
87 extern int Multi_team1_score;
88
89 // ------------------------------------------------------------------------------------
90 // MULTIPLAYER SQUAD WAR FORWARD DECLARATIONS
91 //
92
93 // popup_till_condition do frame function for the host doing verification through the standalone
94 int multi_sw_query_tracker_A();
95
96 // condition do frame function for the standalone querying PXO
97 int multi_sw_query_tracker_B();
98
99 // stuff Multi_sw_request
100 void multi_sw_stuff_request(char *match_code);
101
102 // stuff Multi_sw_result
103 void multi_sw_stuff_result();
104
105 // verify that we have the proper # of players
106 int multi_sw_verify_squad_counts();
107
108
109 // ------------------------------------------------------------------------------------
110 // MULTIPLAYER SQUAD WAR FUNCTIONS
111 //
112
113 // call before loading level - mission sync phase. only the server need do this
114 void multi_sw_level_init()
115 {       
116 }
117
118 // determine if everything is ok to move forward for a squad war match
119 int multi_sw_ok_to_commit()
120 {
121         char *ret;
122         char match_code[MATCH_CODE_LEN] = "";   
123         char bad_response[MAX_SQUAD_RESPONSE_LEN+1];
124
125         memset(bad_response, 0, MAX_SQUAD_RESPONSE_LEN+1);
126
127         // make sure we have enough players per team
128         if(!multi_sw_verify_squad_counts()){
129                 return 0;
130         }               
131
132         // prompt the host for the match code
133         ret = popup_input(0, XSTR("Please enter the match code", 1076), 32);
134         if(ret == NULL){
135                 return 0;
136         }
137         strcpy(match_code, ret);
138
139         strcpy(Multi_sw_match_code, "");
140
141         // if we're the server, do the nice case
142         if(MULTIPLAYER_MASTER){
143                 // stuff match request
144                 multi_sw_stuff_request(match_code);
145                 
146                 // return an MSW_STATUS_* value
147                 if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response) == MSW_STATUS_VALID){                  
148                         // store the match code                 
149                         strncpy(Multi_sw_match_code, match_code, MATCH_CODE_LEN);
150
151                         // success              
152                         return 1;
153                 } 
154                 // do - didn't check out properly
155                 else {
156                         if(strlen(bad_response) > 0){
157                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", bad_response);
158                         } else {
159                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
160                         }
161                 }
162         }
163         // otherwise we have to do it through the standalone - ARRRGHH!
164         else {
165                 // send the query packet and wait for a response
166                 Multi_sw_std_query = -1;
167                 memset(Multi_sw_bad_reply, 0, MAX_SQUAD_RESPONSE_LEN+1);
168                 send_sw_query_packet(SW_STD_START, match_code);
169                 if(popup_till_condition(multi_sw_query_tracker_A, XSTR("&Cancel", 667), XSTR("Validating squad war", 1075)) == 10){
170                         // success
171                         return 1;
172                 } else {
173                         if(strlen(Multi_sw_bad_reply) > 0){
174                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", Multi_sw_bad_reply);
175                         } else {
176                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
177                         }
178                 }
179         }
180
181         // hmm, should probably never get here
182         return 0;
183 }
184
185 // query PXO on the standalone
186 void multi_sw_std_query(char *match_code)
187 {
188         char bad_response[MAX_SQUAD_RESPONSE_LEN+1];
189
190         memset(bad_response, 0, MAX_SQUAD_RESPONSE_LEN+1);
191
192         // stuff match request
193         multi_sw_stuff_request(match_code);     
194
195         strcpy(Multi_sw_match_code, "");
196
197         // return an MSW_STATUS_* value
198         if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response) != MSW_STATUS_VALID){
199                 send_sw_query_packet(SW_STD_BAD, bad_response);
200         } else {
201                 // store the match code
202                 strncpy(Multi_sw_match_code, match_code, MATCH_CODE_LEN);
203                         
204                 send_sw_query_packet(SW_STD_OK, NULL);          
205         }
206 }
207
208 // call to update everything on the tracker
209 #define SEND_AND_DISPLAY(mesg)          do { send_game_chat_packet(Net_player, mesg, MULTI_MSG_ALL, NULL, NULL, 1); multi_display_chat_msg(mesg, 0, 0); } while(0);
210 void multi_sw_report(int stats_saved)
211 {                       
212         char bad_response[MAX_SQUAD_RESPONSE_LEN+1];
213         memset(bad_response, 0, MAX_SQUAD_RESPONSE_LEN+1);      
214
215         // stuff Multi_sw_result
216         multi_sw_stuff_result();        
217
218         // update on PXO        
219         if(stats_saved){
220                 if(multi_fs_tracker_store_sw(&Multi_sw_result, bad_response)){
221                         SEND_AND_DISPLAY(XSTR("<SquadWar results stored on PXO>", 1079));
222                 } else {
223                         SEND_AND_DISPLAY(XSTR("<SquadWar results rejected by PXO>", 1080));
224                         if(strlen(bad_response) > 0){
225                                 SEND_AND_DISPLAY(bad_response);
226                         }
227                 }       
228         }
229         // doh. something was bogus
230         else {
231                 SEND_AND_DISPLAY(XSTR("<SquadWar results invalidated>", 1478));
232         }
233 }
234
235 // ------------------------------------------------------------------------------------
236 // MULTIPLAYER SQUAD WAR FORWARD DEFINITIONS
237 //
238
239 // condition do frame function for the standalone querying PXO
240 int multi_sw_query_tracker_A()
241 {
242         switch(Multi_sw_std_query){
243         // still waiting
244         case -1 :
245                 return 0;
246
247         // failure
248         case 0 :
249                 return 1;
250
251         // successs
252         case 1 :
253                 return 10;
254         }
255
256         // shouldn't get here   
257         return 1;
258 }
259
260 // stuff Multi_sw_request
261 void multi_sw_stuff_request(char *match_code)
262 {
263         int idx;        
264         squad_war_request *s = &Multi_sw_request;
265
266         // stuff squad id #'s, counts, and squad names
267         s->squad_count1 = 0;
268         s->squad_count2 = 0;
269         for(idx=0; idx<MAX_PLAYERS; idx++){
270                 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
271                         // team 0
272                         if(Net_players[idx].p_info.team == 0){
273                                 s->squad_plr1[s->squad_count1++] = Net_players[idx].tracker_player_id;                          
274                         } 
275                         // team 1
276                         else {
277                                 s->squad_plr2[s->squad_count2++] = Net_players[idx].tracker_player_id;                          
278                         }
279                 }
280         }               
281
282         // stuff match code
283         strncpy(s->match_code, match_code, MATCH_CODE_LEN);
284 }
285
286 // verify that we have the proper # of players
287 int multi_sw_verify_squad_counts()
288 {
289         int idx;
290         int team0_count = 0;
291         int team1_count = 0;
292         char err_string[255] = "";
293
294         for(idx=0; idx<MAX_PLAYERS; idx++){             
295                 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
296                         if(Net_players[idx].p_info.team == 0){
297                                 team0_count++;
298                         } else {
299                                 team1_count++;
300                         }
301                 }
302         }
303         if((team0_count < MULTI_SW_MIN_PLAYERS) || (team1_count < MULTI_SW_MIN_PLAYERS)){       
304                 // print up the error string
305                 sprintf(err_string, XSTR("You need to have at least %d players per squad for Squad War", 1073), MULTI_SW_MIN_PLAYERS);
306                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, err_string);
307                 return 0;
308         }
309
310         // we're cool
311         return 1;
312 }
313
314 // stuff Multi_sw_result
315 void multi_sw_stuff_result()
316 {
317         squad_war_result *s = &Multi_sw_result;
318         int idx;
319
320         // stuff match code
321         strncpy(s->match_code, Multi_sw_match_code, MATCH_CODE_LEN);
322
323         // determine what happened
324         switch(multi_team_winner()){
325         // tie
326         case -1:
327                 s->result = 0;
328                 s->squad_count1 = 0;
329                 s->squad_count2 = 0;
330                 break;
331
332         // team 0 won
333         case 0:
334                 s->result = 1;
335                 // stuff squad id #'s, counts, and squad names
336                 s->squad_count1 = 0;
337                 s->squad_count2 = 0;
338                 for(idx=0; idx<MAX_PLAYERS; idx++){
339                         if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
340                                 // team 0
341                                 if(Net_players[idx].p_info.team == 0){
342                                         s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;                               
343                                 } 
344                                 // team 1
345                                 else {
346                                         s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;                                
347                                 }
348                         }
349                 }               
350                 break;
351
352         // team 1 won
353         case 1:
354                 s->result = 1;
355                 // stuff squad id #'s, counts, and squad names
356                 s->squad_count1 = 0;
357                 s->squad_count2 = 0;
358                 for(idx=0; idx<MAX_PLAYERS; idx++){
359                         if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
360                                 // team 1
361                                 if(Net_players[idx].p_info.team == 1){
362                                         s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;                               
363                                 } 
364                                 // team 0
365                                 else {
366                                         s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;                                
367                                 }
368                         }
369                 }               
370                 break;
371         }
372 }
373