]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/multi_sw.cpp
popup() -> popup_sync() change for FS1 builds
[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         const char *ret;
122         char match_code[MATCH_CODE_LEN] = "";   
123         char bad_response[MAX_SQUAD_RESPONSE_LEN+1] = "";
124
125
126         // make sure we have enough players per team
127         if(!multi_sw_verify_squad_counts()){
128                 return 0;
129         }               
130
131         // prompt the host for the match code
132         ret = popup_input_sync(0, XSTR("Please enter the match code", 1076), 32);
133         if(ret == NULL){
134                 return 0;
135         }
136         SDL_strlcpy(match_code, ret, SDL_arraysize(match_code));
137
138         SDL_strlcpy(Multi_sw_match_code, "", SDL_arraysize(Multi_sw_match_code));
139
140         // if we're the server, do the nice case
141         if(MULTIPLAYER_MASTER){
142                 // stuff match request
143                 multi_sw_stuff_request(match_code);
144                 
145                 // return an MSW_STATUS_* value
146                 if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response, SDL_arraysize(bad_response)) == MSW_STATUS_VALID){
147                         // store the match code                 
148                         SDL_strlcpy(Multi_sw_match_code, match_code, SDL_arraysize(Multi_sw_match_code));
149
150                         // success              
151                         return 1;
152                 } 
153                 // do - didn't check out properly
154                 else {
155                         if(strlen(bad_response) > 0){
156                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", bad_response);
157                         } else {
158                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
159                         }
160                 }
161         }
162         // otherwise we have to do it through the standalone - ARRRGHH!
163         else {
164                 // send the query packet and wait for a response
165                 Multi_sw_std_query = -1;
166                 memset(Multi_sw_bad_reply, 0, MAX_SQUAD_RESPONSE_LEN+1);
167                 send_sw_query_packet(SW_STD_START, match_code);
168                 if(popup_till_condition(multi_sw_query_tracker_A, XSTR("&Cancel", 667), XSTR("Validating squad war", 1075)) == 10){
169                         // success
170                         return 1;
171                 } else {
172                         if(strlen(Multi_sw_bad_reply) > 0){
173                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", Multi_sw_bad_reply);
174                         } else {
175                                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
176                         }
177                 }
178         }
179
180         // hmm, should probably never get here
181         return 0;
182 }
183
184 // query PXO on the standalone
185 void multi_sw_std_query(char *match_code)
186 {
187         char bad_response[MAX_SQUAD_RESPONSE_LEN+1];
188
189         // stuff match request
190         multi_sw_stuff_request(match_code);     
191
192         SDL_strlcpy(Multi_sw_match_code, "", SDL_arraysize(Multi_sw_match_code));
193
194         // return an MSW_STATUS_* value
195         if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response, SDL_arraysize(bad_response)) != MSW_STATUS_VALID){
196                 send_sw_query_packet(SW_STD_BAD, bad_response);
197         } else {
198                 // store the match code
199                 SDL_strlcpy(Multi_sw_match_code, match_code, SDL_arraysize(Multi_sw_match_code));
200                         
201                 send_sw_query_packet(SW_STD_OK, NULL);          
202         }
203 }
204
205 // call to update everything on the tracker
206 #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);
207 void multi_sw_report(int stats_saved)
208 {                       
209         char bad_response[MAX_SQUAD_RESPONSE_LEN+1] = "";
210
211         // stuff Multi_sw_result
212         multi_sw_stuff_result();        
213
214         // update on PXO        
215         if(stats_saved){
216                 if ( multi_fs_tracker_store_sw(&Multi_sw_result, bad_response, SDL_arraysize(bad_response)) ) {
217                         SEND_AND_DISPLAY(XSTR("<SquadWar results stored on PXO>", 1079));
218                 } else {
219                         SEND_AND_DISPLAY(XSTR("<SquadWar results rejected by PXO>", 1080));
220                         if(strlen(bad_response) > 0){
221                                 SEND_AND_DISPLAY(bad_response);
222                         }
223                 }       
224         }
225         // doh. something was bogus
226         else {
227                 SEND_AND_DISPLAY(XSTR("<SquadWar results invalidated>", 1478));
228         }
229 }
230
231 // ------------------------------------------------------------------------------------
232 // MULTIPLAYER SQUAD WAR FORWARD DEFINITIONS
233 //
234
235 // condition do frame function for the standalone querying PXO
236 int multi_sw_query_tracker_A()
237 {
238         switch(Multi_sw_std_query){
239         // still waiting
240         case -1 :
241                 return 0;
242
243         // failure
244         case 0 :
245                 return 1;
246
247         // successs
248         case 1 :
249                 return 10;
250         }
251
252         // shouldn't get here   
253         return 1;
254 }
255
256 // stuff Multi_sw_request
257 void multi_sw_stuff_request(char *match_code)
258 {
259         int idx;        
260         squad_war_request *s = &Multi_sw_request;
261
262         // stuff squad id #'s, counts, and squad names
263         s->squad_count1 = 0;
264         s->squad_count2 = 0;
265         for(idx=0; idx<MAX_PLAYERS; idx++){
266                 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
267                         // team 0
268                         if(Net_players[idx].p_info.team == 0){
269                                 s->squad_plr1[s->squad_count1++] = Net_players[idx].tracker_player_id;                          
270                         } 
271                         // team 1
272                         else {
273                                 s->squad_plr2[s->squad_count2++] = Net_players[idx].tracker_player_id;                          
274                         }
275                 }
276         }               
277
278         // stuff match code
279         SDL_strlcpy(s->match_code, match_code, SDL_arraysize(s->match_code));
280 }
281
282 // verify that we have the proper # of players
283 int multi_sw_verify_squad_counts()
284 {
285         int idx;
286         int team0_count = 0;
287         int team1_count = 0;
288         char err_string[255] = "";
289
290         for(idx=0; idx<MAX_PLAYERS; idx++){             
291                 if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
292                         if(Net_players[idx].p_info.team == 0){
293                                 team0_count++;
294                         } else {
295                                 team1_count++;
296                         }
297                 }
298         }
299         if((team0_count < MULTI_SW_MIN_PLAYERS) || (team1_count < MULTI_SW_MIN_PLAYERS)){       
300                 // print up the error string
301                 SDL_snprintf(err_string, SDL_arraysize(err_string), XSTR("You need to have at least %d players per squad for Squad War", 1073), MULTI_SW_MIN_PLAYERS);
302                 popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, err_string);
303                 return 0;
304         }
305
306         // we're cool
307         return 1;
308 }
309
310 // stuff Multi_sw_result
311 void multi_sw_stuff_result()
312 {
313         squad_war_result *s = &Multi_sw_result;
314         int idx;
315
316         // stuff match code
317         SDL_strlcpy(s->match_code, Multi_sw_match_code, SDL_arraysize(s->match_code));
318
319         // determine what happened
320         switch(multi_team_winner()){
321         // tie
322         case -1:
323                 s->result = 0;
324                 s->squad_count1 = 0;
325                 s->squad_count2 = 0;
326                 break;
327
328         // team 0 won
329         case 0:
330                 s->result = 1;
331                 // stuff squad id #'s, counts, and squad names
332                 s->squad_count1 = 0;
333                 s->squad_count2 = 0;
334                 for(idx=0; idx<MAX_PLAYERS; idx++){
335                         if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
336                                 // team 0
337                                 if(Net_players[idx].p_info.team == 0){
338                                         s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;                               
339                                 } 
340                                 // team 1
341                                 else {
342                                         s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;                                
343                                 }
344                         }
345                 }               
346                 break;
347
348         // team 1 won
349         case 1:
350                 s->result = 1;
351                 // stuff squad id #'s, counts, and squad names
352                 s->squad_count1 = 0;
353                 s->squad_count2 = 0;
354                 for(idx=0; idx<MAX_PLAYERS; idx++){
355                         if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
356                                 // team 1
357                                 if(Net_players[idx].p_info.team == 1){
358                                         s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;                               
359                                 } 
360                                 // team 0
361                                 else {
362                                         s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;                                
363                                 }
364                         }
365                 }               
366                 break;
367         }
368 }
369