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