Exemple #1
0
// display the medals screen for this player
void multi_pinfo_do_medals()
{
#ifdef FS2DEMO
	game_feature_not_in_demo_popup();
#elif defined(SAGA_NO_MULTIPLAYER_YET)
	game_feature_not_supported_by_saga_yet();
#else
	int ret_code;

	// initialize the medals screen
	medal_main_init(Multi_pinfo_popup_player->m_player, MM_POPUP);

	// run the medals screen until it says that it should be closed
	do
	{
		// set frametime and run common functions
		game_set_frametime(-1);
		game_do_state_common(gameseq_get_state());

		// run the medals screen
		ret_code = medal_main_do();
	} while (ret_code && !Multi_pinfo_popup_done);

	// close the medals screen down
	medal_main_close();

	// restore the proper palette
	multi_pinfo_set_palette();
#endif
}
// (client) call when receiving a packet indicating we should pause
void multi_pause_pause()
{
	int idx;

	// if we're already paused, don't do anything
	if(Multi_pause_status){
		return;
	}

	// sanity check
	Assert(!Multi_pause_status);

	// mark the game as being paused
	Multi_pause_status = 1;

	// if we're not already in the pause state
	if(gameseq_get_state() != GS_STATE_MULTI_PAUSED){
		// jump into the paused state 
		gameseq_post_event(GS_EVENT_MULTI_PAUSE);

		// mark the netgame state
		Netgame.game_state = NETGAME_STATE_PAUSED;					
	}

	// if we're the server of the game, send a packet which will pause the clients in the game now
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		for(idx=0;idx<MAX_PLAYERS;idx++){
			if(MULTI_CONNECTED(Net_players[idx]) && (Net_player != &Net_players[idx])){
				send_client_update_packet(&Net_players[idx]);
			}
		}
	}
}
Exemple #3
0
// run the popup in a tight loop (no states)
void multi_pinfo_popup_do()
{
	int k;

	// if there was an error in initialization, return immediately
	if (Multi_pinfo_popup_error)
	{
		return;
	}

	// tight loop
	while (!Multi_pinfo_popup_done)
	{
		multi_pinfo_maybe_reload_pic(&Mp_pilot);
		multi_pinfo_maybe_reload_pic(&Mp_squad);

		// process the window
		k = Multi_pinfo_window.process();
		switch (k)
		{
		case KEY_ESC :
			Multi_pinfo_popup_done = 1;
			break;
		}

		// check button presses
		multi_pinfo_popup_check_buttons();

		// set frametime and run background stuff
		game_set_frametime(-1);
		game_do_state_common(gameseq_get_state());

		// draw the background bitmap and the ui window over it
		Assert(Multi_pinfo_screen_save != -1);
		gr_reset_clip();
		gr_restore_screen(Multi_pinfo_screen_save);

		// grey the screen
		gr_set_shader(&Grey_shader);
		gr_shade(0, 0, gr_screen.clip_width, gr_screen.clip_height, false);

		// draw the background bitmap
		gr_set_bitmap(Multi_pinfo_bitmap);
		gr_bitmap(0, 0);

		// blit the selected pilot image
		multi_pinfo_blit_pilot_image();

		// blit the squadron logo
		multi_pinfo_blit_squadron_logo();

		// blit the player statistics
		multi_pinfo_blit_player_stats();

		// draw the ui window and flip
		Multi_pinfo_window.draw();
		gr_flip();
	}
}
// process all endgame related events
void multi_endgame_process()
{
	if ( Multi_endgame_processing )
		return;

	Multi_endgame_processing = 1;

	// check to see if we need to be warping out (strange transition possibilities)
	multi_endgame_check_for_warpout();
	
	// if we're the server of the game
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		// if we're not waiting for clients to leave, do nothing
		if(!Multi_endgame_server_waiting){
			Multi_endgame_processing = 0;
			return;
		}

		// if a popup is already active, do nothing		
		if(popup_active()){
			Multi_endgame_processing = 0;
			return;
		}

		// otherwise popup until things are hunky-dory
		if(!multi_endgame_server_ok_to_leave()){
			if(Game_mode & GM_STANDALONE_SERVER){
				while(!multi_endgame_server_ok_to_leave()){
					// run networking, etc.
					game_set_frametime(-1);
					game_do_state_common(gameseq_get_state());
				}
			} else {
				popup_till_condition( multi_endgame_server_ok_to_leave , XSTR("&Cancel",645), XSTR("Waiting for clients to disconnect",646));		
			}
		}

		// mark myself as not waiting and get out
		multi_endgame_cleanup();	
	} else {
		// if we're not waiting to leave the game, do nothing
		if(!Multi_endgame_client_waiting){
			Multi_endgame_processing = 0;
			return;
		}

		// otherwise, check to see if there is a popup active
		if(popup_active()){
			Multi_endgame_processing = 0;
			return;
		}

		// if not, then we are good to leave		
		multi_endgame_cleanup();
	}

	Multi_endgame_processing = 0;
}
int popup_do_with_condition(popup_info *pi, int flags, int(*condition)())
{
	int screen_id, choice = -1, done = 0;
	int test;
	screen_id = gr_save_screen();
	if ( popup_init(pi, flags) == -1 )
		return -1;

	int old_max_w_unscaled = gr_screen.max_w_unscaled;
	int old_max_h_unscaled = gr_screen.max_h_unscaled;
	int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
	int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;

	gr_reset_screen_scale();

	while(!done) {
		int k;

		os_poll();
		
		game_set_frametime(-1);
		game_do_state_common(gameseq_get_state());	// do stuff common to all states 
		gr_restore_screen(screen_id);

		// draw one frame first
		Popup_window.draw();
		popup_force_draw_buttons(pi);
		popup_draw_msg_text(pi, flags);
		popup_draw_button_text(pi, flags);
		gr_flip();

		// test the condition function or process for the window
		if ((test = condition()) > 0) {
			done = 1;
			choice = test;
		} else {
			k = Popup_window.process();						// poll for input, handle mouse
			choice = popup_process_keys(pi, k, flags);
			if ( choice != POPUP_NOCHANGE ) {
				done=1;
			}

			if ( !done ) {
				choice = popup_check_buttons(pi);
				if ( choice != POPUP_NOCHANGE ) {
					done=1;
				}
			}
		}		
	}

	gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed);

	popup_close(pi,screen_id);
	return choice;
}
// (server) evaluate a pause request from the given player (should call for himself as well)
void multi_pause_server_eval_request(net_player *pl, int pause)
{
	int cur_state;
	
	// if this is a pause request and we're already in the pause state, do nothing
	if(pause && Multi_pause_status){
		return;
	}

	// if this is an unpause request and we're already unpaused, do nothing
	if(!pause && !Multi_pause_status){
		return;
	}

	// get the current state (don't allow pausing from certain states
	cur_state = gameseq_get_state();
	if((cur_state == GS_STATE_DEBRIEF) || (cur_state == GS_STATE_MULTI_MISSION_SYNC) || (cur_state == GS_STATE_BRIEFING) ||
		(cur_state == GS_STATE_STANDALONE_POSTGAME) || (cur_state == GS_STATE_MULTI_STD_WAIT) || (cur_state == GS_STATE_WEAPON_SELECT) ||
		(cur_state == GS_STATE_TEAM_SELECT) || (cur_state == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)){
		return;
	}
	
	// if this is a pause request
	if(pause){
		// record who the pauser is
		Multi_pause_pauser = pl;

		// pause the game
		multi_pause_pause();		
	}
	// if this is an unpause request
	else {
		// if this guy is allowed to unpause the game, do so
		if(multi_pause_can_unpause(pl)){
			// unmark the "pauser"
			Multi_pause_pauser = NULL;

			// unpause the game
			multi_pause_unpause();			
		}
	}	
}
// display the medals screen for this player
void multi_pinfo_do_medals()
{
	int ret_code;

	// initialize the medals screen
	medal_main_init(Multi_pinfo_popup_player->m_player,MM_POPUP);

	// run the medals screen until it says that it should be closed
	do {
		// set frametime and run common functions
		game_set_frametime(-1);
		game_do_state_common(gameseq_get_state());

		// run the medals screen
		ret_code = medal_main_do();		
	} while(ret_code && !Multi_pinfo_popup_done);

	// close the medals screen down
	medal_main_close();
}
Exemple #8
0
// launch_context_help() will switch to a context sensitive help state
void launch_context_help()
{
	// look at the state the game was in when F1 was pressed
	Source_game_state = gameseq_get_state();

	switch (Source_game_state)
	{

	case GS_STATE_MAIN_MENU:
#if !defined(PRESS_TOUR_BUILD) && !defined(PD_BUILD)
			int main_hall_num;
		main_hall_num = (main_hall_id() == 0) ? MH_OVERLAY : MH2_OVERLAY;
		if (!help_overlay_active(main_hall_num))
		{
			help_overlay_set_state(main_hall_num, 1);
		}
		else
		{
			help_overlay_set_state(main_hall_num, 0);
		}
#endif
			break;

	case GS_STATE_GAME_PLAY:
	case GS_STATE_GAME_PAUSED:
	case GS_STATE_TRAINING_PAUSED:
		gameseq_post_event(GS_EVENT_GAMEPLAY_HELP);
		break;

	case GS_STATE_BRIEFING:
		if (!help_overlay_active(BR_OVERLAY))
		{
			help_overlay_set_state(BR_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(BR_OVERLAY, 0);
		}
		break;

	case GS_STATE_SHIP_SELECT:
		if (!help_overlay_active(SS_OVERLAY))
		{
			help_overlay_set_state(SS_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(SS_OVERLAY, 0);
		}
		break;

	case GS_STATE_WEAPON_SELECT:
		if (!help_overlay_active(WL_OVERLAY))
		{
			help_overlay_set_state(WL_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(WL_OVERLAY, 0);
		}
		break;

	case GS_STATE_BARRACKS_MENU:
		if (!help_overlay_active(BARRACKS_OVERLAY))
		{
			help_overlay_set_state(BARRACKS_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(BARRACKS_OVERLAY, 0);
		}
		break;

	case GS_STATE_CONTROL_CONFIG:
		if (!help_overlay_active(CONTROL_CONFIG_OVERLAY))
		{
			help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
		}
		break;

	case GS_STATE_DEBRIEF:
		if (!help_overlay_active(DEBRIEFING_OVERLAY))
		{
			help_overlay_set_state(DEBRIEFING_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(DEBRIEFING_OVERLAY, 0);
		}
		break;

	case GS_STATE_MULTI_HOST_SETUP:
		if (!help_overlay_active(MULTI_CREATE_OVERLAY))
		{
			help_overlay_set_state(MULTI_CREATE_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(MULTI_CREATE_OVERLAY, 0);
		}
		break;

	case GS_STATE_MULTI_START_GAME:
		if (!help_overlay_active(MULTI_START_OVERLAY))
		{
			help_overlay_set_state(MULTI_START_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(MULTI_START_OVERLAY, 0);
		}
		break;
		/*
				case GS_STATE_NET_CHAT:
					if (!help_overlay_active(FS2OX_OVERLAY) ) {
						help_overlay_set_state(FS2OX_OVERLAY, 1);
					}
					else {
						help_overlay_set_state(FS2OX_OVERLAY, 1);
					}
					break;
		*/
	case GS_STATE_MULTI_JOIN_GAME:
		if (!help_overlay_active(MULTI_JOIN_OVERLAY))
		{
			help_overlay_set_state(MULTI_JOIN_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(MULTI_JOIN_OVERLAY, 0);
		}
		break;

	case GS_STATE_HOTKEY_SCREEN:
		if (!help_overlay_active(HOTKEY_OVERLAY))
		{
			help_overlay_set_state(HOTKEY_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(HOTKEY_OVERLAY, 0);
		}
		break;

	case GS_STATE_CAMPAIGN_ROOM:
		if (!help_overlay_active(CAMPAIGN_ROOM_OVERLAY))
		{
			help_overlay_set_state(CAMPAIGN_ROOM_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(CAMPAIGN_ROOM_OVERLAY, 0);
		}
		break;

	case GS_STATE_SIMULATOR_ROOM:
		if (!help_overlay_active(SIM_ROOM_OVERLAY))
		{
			help_overlay_set_state(SIM_ROOM_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(SIM_ROOM_OVERLAY, 0);
		}
		break;

	case GS_STATE_TECH_MENU:
		{
			if (!help_overlay_active(TECH_ROOM_OVERLAY))
			{
				help_overlay_set_state(TECH_ROOM_OVERLAY, 1);
			}
			else
			{
				help_overlay_set_state(TECH_ROOM_OVERLAY, 0);
			}
			break;
		}

	case GS_STATE_CMD_BRIEF:
		if (!help_overlay_active(CMD_BRIEF_OVERLAY))
		{
			help_overlay_set_state(CMD_BRIEF_OVERLAY, 1);
		}
		else
		{
			help_overlay_set_state(CMD_BRIEF_OVERLAY, 0);
		}
		break;

	default:
		nprintf(("Warning", "WARNING ==> There is no context help available for state %s\n",
				 GS_state_text[Source_game_state - 1]));
		break;

	} // end switch
}
// launch_context_help() will switch to a context sensitive help state
void launch_context_help()
{
	int overlay_id = -1;
	int resolution_index = gr_screen.res;

	// look at the state the game was in when F1 was pressed
	Source_game_state = gameseq_get_state();

	switch (Source_game_state) {

		case GS_STATE_MAIN_MENU:
			overlay_id = main_hall_get_overlay_id();
			resolution_index = main_hall_get_overlay_resolution_index();
			break;

		case GS_STATE_GAME_PLAY:
		case GS_STATE_GAME_PAUSED:
		case GS_STATE_TRAINING_PAUSED:
			gameseq_post_event(GS_EVENT_GAMEPLAY_HELP);
			break;

		case GS_STATE_BRIEFING:
			overlay_id = Briefing_overlay_id;
			break;

		case GS_STATE_SHIP_SELECT:
			overlay_id = Ship_select_overlay_id;
			break;

		case GS_STATE_WEAPON_SELECT:
			overlay_id = Weapon_select_overlay_id;
			break;

		case GS_STATE_BARRACKS_MENU:
			overlay_id = Barracks_overlay_id;
			break;

		case GS_STATE_CONTROL_CONFIG:
			overlay_id = Control_config_overlay_id;
			break;

		case GS_STATE_DEBRIEF:
			overlay_id = Debrief_overlay_id;
			break;

		case GS_STATE_MULTI_HOST_SETUP:
			overlay_id = Multi_create_overlay_id;
			break;

		case GS_STATE_MULTI_START_GAME:
			overlay_id = Multi_sg_overlay_id;
			break;

		case GS_STATE_MULTI_JOIN_GAME:
			overlay_id = Multi_join_overlay_id;
			break;

		case GS_STATE_HOTKEY_SCREEN:
			overlay_id = Hotkey_overlay_id;
			break;

		case GS_STATE_CAMPAIGN_ROOM:
			overlay_id = Campaign_room_overlay_id;
			break;

		case GS_STATE_SIMULATOR_ROOM:
			overlay_id = Sim_room_overlay_id;
			break;

		case GS_STATE_TECH_MENU:
			overlay_id = Techroom_overlay_id;
			break;

		case GS_STATE_CMD_BRIEF:
			overlay_id = Cmd_brief_overlay_id;
			break;

		default:
			nprintf(("Warning","WARNING ==> There is no context help available for state %s\n", GS_state_text[Source_game_state-1]));
			break;

	} // end switch

	if (overlay_id >= 0) {
		if ( !help_overlay_active(overlay_id) ) {
			help_overlay_set_state(overlay_id, resolution_index, 1);
		}
		else {
			help_overlay_set_state(overlay_id, resolution_index, 0);
		}
	}
}
// called when a given netgame is about to end completely
void multi_endgame_cleanup()
{
	int idx;

	hud_config_as_player();

	send_leave_game_packet();			

	// flush all outgoing io, force all packets through
	multi_io_send_buffered_packets();
		
	// mark myself as disconnected
	if(!(Game_mode & GM_STANDALONE_SERVER)){
		Net_player->flags &= ~(NETINFO_FLAG_CONNECTED|NETINFO_FLAG_DO_NETWORKING);
	}
	
	/*this is a semi-hack so that if we're the master and we're quitting, we don't get an assert

    Karajorma - From the looks of things this code actually CAUSES an Int3 and doesn't cause an assert anymore
	besides if the game is over why are we setting flags on a Player_obj anyway? 

	if((Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Player_obj != NULL)){
		Player_obj->flags &= ~(OF_PLAYER_SHIP);
		obj_set_flags( Player_obj, Player_obj->flags | OF_COULD_BE_PLAYER );
	}
	*/
	
	// shut my socket down (will also let the server know i've received any notifications/error from him)
	// psnet_rel_close_socket( &(Net_player->reliable_socket) );

	// 11/18/98 - DB, changed the above to kill all sockets. Its the safest thing to do
	for(idx=0; idx<MAX_PLAYERS; idx++){
		psnet_rel_close_socket(&Net_players[idx].reliable_socket);
		Net_players[idx].reliable_socket = INVALID_SOCKET;
	}

	// set the game quitting flag in our local netgame info - this will _insure_ that even if we miss a packet or
	// there is some sequencing error, the next time through the multi_do_frame() loop, the game will be ended
	// Netgame.flags |= (NG_FLAG_QUITTING | NG_FLAG_ENDED);

	// close all open SPX/TCP reliable sockets
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		// do it for all players, since we're leaving anyway.
		for(idx=0;idx<MAX_PLAYERS;idx++){
			// 6/25/98 -- MWA delete all players from the game

			if ( &Net_players[idx] != Net_player ) {
				delete_player( idx );
			}			
		}
	}	

	// if we're currently in the pause state, pop back into gameplay first
	if(gameseq_get_state() == GS_STATE_MULTI_PAUSED){
		gameseq_pop_state();
	}

	// handle game disconnect from FS2NetD (NOTE: must be done *before* standalone is reset!!)
	if ( MULTI_IS_TRACKER_GAME && (Net_player->flags & NETINFO_FLAG_AM_MASTER) ) {
		fs2netd_gameserver_disconnect();
	}

	if (Game_mode & GM_STANDALONE_SERVER) {
		// multi_standalone_quit_game();		
		multi_standalone_reset_all();
	} else {		
		Player->flags |= PLAYER_FLAGS_IS_MULTI;		

		// if we're in Parallax Online mode, log back in there	
		gameseq_post_event(GS_EVENT_MULTI_JOIN_GAME);		

		// if we have an error code, bring up the discon popup						
		if ( ((Multi_endgame_notify_code != -1) || (Multi_endgame_error_code != -1)) && !(Game_mode & GM_STANDALONE_SERVER) ) {
			multi_endgame_popup(Multi_endgame_notify_code,Multi_endgame_error_code,Multi_endgame_wsa_error);			
		}		
	}

	/*
	extern CFILE *obj_stream;
	if(obj_stream != NULL){
		cfclose(obj_stream);
		obj_stream = NULL;
	}
	*/	

	// unload the multiplayer common interface palette
	multi_common_unload_palette();
	
	// reinitialize endgame stuff
	// multi_endgame_init();
}
// general quit function, with optional notification, error, and winsock error codes
int multi_quit_game(int prompt, int notify_code, int err_code, int wsa_error)
{
	int ret_val,quit_already;

	// check for reentrancy
	if(Multi_quit_game){
		return 0;
	}

	// if we're not connected or have not net-player
	if((Net_player == NULL) || !(Net_player->flags & NETINFO_FLAG_CONNECTED)){
		return 1;
	}

	// reentrancy
	Multi_quit_game = 1;

	quit_already = 0;

	// reset my control info so that I don't continually do whacky stuff.  This is ugly
	//player_control_reset_ci( &Player->ci );
	if ( Game_mode & GM_IN_MISSION ) {
		memset(&Player->ci, 0, sizeof(Player->ci) );
		Player->ci.afterburner_stop = 1;
		physics_read_flying_controls( &Player_obj->orient, &Player_obj->phys_info, &(Player->ci), flFrametime);
	}

	// CASE 1 - response to a user request
	// if there is no associated notification or error code, don't override the prompt argument
	if((err_code == -1) && (notify_code == -1)){
		// if we're the server and we're already waiting for clients to leave, don't do anything
		if((Net_player->flags & NETINFO_FLAG_AM_MASTER) && Multi_endgame_server_waiting){
			Multi_quit_game = 0;
			return 0;
		}

		// if we're the client and we're already waiting to leave, don't do anythin
		if(!(Net_player->flags & NETINFO_FLAG_AM_MASTER) && Multi_endgame_client_waiting){
			Multi_quit_game = 0;
			return 0;
		}

		// see if we should be prompting the host for confirmation
		if((prompt==PROMPT_HOST || prompt==PROMPT_ALL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)){
			int p_flags;

			p_flags = PF_USE_AFFIRMATIVE_ICON | PF_USE_NEGATIVE_ICON | PF_BODY_BIG;
			if ( Game_mode & GM_IN_MISSION )
				p_flags |= PF_RUN_STATE;

			ret_val = popup(p_flags,2,POPUP_CANCEL,POPUP_OK,XSTR("Warning - quitting will end the game for all players!",647));

			// check for host cancel
			if((ret_val == 0) || (ret_val == -1)){
				Multi_quit_game = 0;
				return 0;
			}

			// set this so that under certain circumstances, we don't call the popup below us as well
			quit_already = 1;
		}

		// see if we should be prompting the client for confirmation
		if((prompt==PROMPT_CLIENT || prompt==PROMPT_ALL) && !quit_already){
			ret_val = popup(PF_USE_AFFIRMATIVE_ICON | PF_USE_NEGATIVE_ICON | PF_BODY_BIG,2,POPUP_NO,POPUP_YES,XSTR("Are you sure you want to quit?",648));

			// check for host cancel
			if((ret_val == 0) || (ret_val == -1)){
				Multi_quit_game = 0;
				return 0;
			}
			quit_already = 1;
		}

		// if i'm the server of the game, tell all clients that i'm leaving, then wait
		if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
			send_netgame_end_error_packet(MULTI_END_NOTIFY_SERVER_LEFT,MULTI_END_ERROR_NONE);

			// set the waiting flag and the waiting timestamp
			Multi_endgame_server_waiting = 1;
			Multi_endgame_server_wait_stamp = MULTI_ENDGAME_SERVER_WAIT;
		}
		// if i'm the client, quit now
		else {
			multi_endgame_cleanup();
		}
	}
	// CASE 2 - response to an error code or packet from the server
	// this is the case where we're being forced to quit the game because of some error or other notification
	else {				
		// if i'm the server, send a packet to the clients telling them that I'm leaving and why
		if((Net_player->flags & NETINFO_FLAG_AM_MASTER) && !Multi_endgame_server_waiting){
			// if we're in the debrief state, mark down that the server has left the game
			if(((gameseq_get_state() == GS_STATE_DEBRIEF) || (gameseq_get_state() == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)) && !(Game_mode & GM_STANDALONE_SERVER)){
				multi_debrief_server_left();

				// add a message to the chatbox
				multi_display_chat_msg(XSTR("<Team captains have left>",649),0,0);				
				
				// set ourselves to be "not quitting"
				Multi_quit_game = 0;

				// tell the users, the game has ended
				send_netgame_end_error_packet(notify_code,err_code);				
				return 0;
			}

			send_netgame_end_error_packet(notify_code,err_code);			

			// store the globals 
			Multi_endgame_notify_code = notify_code;
			Multi_endgame_error_code = err_code;
			Multi_endgame_wsa_error = wsa_error;

			// by setting this, multi_endgame_process() will know to check and see if it is ok for us to leave
			Multi_endgame_server_waiting = 1;				
			Multi_endgame_server_wait_stamp = MULTI_ENDGAME_SERVER_WAIT;
		}
		// if i'm the client, set the error codes and leave the game now
		else if(!Multi_endgame_client_waiting){
			// if we're in the debrief state, mark down that the server has left the game
			if((gameseq_get_state() == GS_STATE_DEBRIEF) || (gameseq_get_state() == GS_STATE_MULTI_DOGFIGHT_DEBRIEF)){
				multi_debrief_server_left();

				// add a message to the chatbox
				multi_display_chat_msg(XSTR("<The server has ended the game>",650),0,0);

				// shut our reliable socket to the server down
				psnet_rel_close_socket(&Net_player->reliable_socket);
				Net_player->reliable_socket = INVALID_SOCKET;

				// remove our do-notworking flag
				Net_player->flags &= ~(NETINFO_FLAG_DO_NETWORKING);
				
				Multi_quit_game = 0;
				return 0;
			}

			Multi_endgame_notify_code = notify_code;
			Multi_endgame_error_code = err_code;
			Multi_endgame_wsa_error = wsa_error;

			// by setting this, multi_endgame_process() will know to check and see if it is ok for us to leave
			Multi_endgame_client_waiting = 1;			
		}
	}		

	// unset the reentrancy flag
	Multi_quit_game = 0;

	return 1;
}
// exit: -1						=>	error
//			0..nchoices-1		=> choice
int popup_do(popup_info *pi, int flags)
{
	int screen_id, choice = -1, done = 0;

	if ( popup_init(pi, flags) == -1 ){
		return -1;
	}

	screen_id = gr_save_screen();

	int old_max_w_unscaled = gr_screen.max_w_unscaled;
	int old_max_h_unscaled = gr_screen.max_h_unscaled;
	int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed;
	int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed;

	gr_reset_screen_scale();

	while(!done) {
		int k;

		os_poll();

		// if we were killed by a call to popup_kill_any_active(), kill the popup
		if(Popup_should_die){
			choice = -1;
			break;
		}

		// if we're flagged as should be running the state underneath, then do so
		if(flags & PF_RUN_STATE){
			game_do_state(gameseq_get_state());
		}
		// otherwise just run the common functions (for networking,etc)
		else {
			game_set_frametime(-1);
			game_do_state_common(gameseq_get_state(),flags & PF_NO_NETWORKING);	// do stuff common to all states 
		}

		k = Popup_window.process();						// poll for input, handle mouse
		choice = popup_process_keys(pi, k, flags);
		if ( choice != POPUP_NOCHANGE ) {
			done=1;
		}

		if ( !done ) {
			choice = popup_check_buttons(pi);
			if ( choice != POPUP_NOCHANGE ) {
				done=1;
			}
		}

		// don't draw anything 
		if(!(flags & PF_RUN_STATE)){
			gr_restore_screen(screen_id);
		}

		// if this is an input popup, store the input text
		if(flags & PF_INPUT){
			Popup_input.get_text(pi->input_text);
		}

		Popup_window.draw();
		popup_force_draw_buttons(pi);
		popup_draw_msg_text(pi, flags);
		popup_draw_button_text(pi, flags);
		gr_flip();
	}

	gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed);

	popup_close(pi,screen_id);
	return choice;
}
Exemple #13
0
bool ConditionedHook::ConditionsValid(int action, object* objp)
{
	uint i;

	//Return false if any conditions are not met
	script_condition* scp;
	ship_info* sip;
	for (i = 0; i < MAX_HOOK_CONDITIONS; i++)
	{
		scp = &Conditions[i];
		switch (scp->condition_type)
		{
		case CHC_STATE:
			if (gameseq_get_depth() < 0)
				return false;
			if (stricmp(GS_state_text[gameseq_get_state(0)], scp->data.name))
				return false;
			break;
		case CHC_SHIPTYPE:
			if (objp == NULL || objp->type != OBJ_SHIP)
				return false;
			sip = &Ship_info[Ships[objp->instance].ship_info_index];
			if (sip->class_type < 0)
				return false;
			if (stricmp(Ship_types[sip->class_type].name, scp->data.name))
				return false;
		case CHC_SHIPCLASS:
			if (objp == NULL || objp->type != OBJ_SHIP)
				return false;
			if (stricmp(Ship_info[Ships[objp->instance].ship_info_index].name, scp->data.name))
				return false;
			break;
		case CHC_SHIP:
			if (objp == NULL || objp->type != OBJ_SHIP)
				return false;
			if (stricmp(Ships[objp->instance].ship_name, scp->data.name))
				return false;
			break;
		case CHC_MISSION:
			{
				//WMC - Get mission filename with Mission_filename
				//I don't use Game_current_mission_filename, because
				//Mission_filename is valid in both fs2_open and FRED
				size_t len = strlen(Mission_filename);
				if (!len)
					return false;
				if (len > 4 && !stricmp(&Mission_filename[len - 4], ".fs2"))
					len -= 4;
				if (strnicmp(scp->data.name, Mission_filename, len))
					return false;
				break;
			}
		case CHC_CAMPAIGN:
			{
				size_t len = strlen(Campaign.filename);
				if (!len)
					return false;
				if (len > 4 && !stricmp(&Mission_filename[len - 4], ".fc2"))
					len -= 4;
				if (strnicmp(scp->data.name, Mission_filename, len))
					return false;
				break;
			}
		case CHC_WEAPONCLASS:
			if (objp == NULL || objp->type != OBJ_WEAPON)
				return false;
			if (stricmp(Weapon_info[Weapons[objp->instance].weapon_info_index].name, scp->data.name))
				return false;
			break;
		case CHC_OBJECTTYPE:
			if (objp == NULL)
				return false;
			if (stricmp(Object_type_names[objp->type], scp->data.name))
				return false;
			break;
		case CHC_KEYPRESS:
			{
				extern int Current_key_down;
				if (gameseq_get_depth() < 0)
					return false;
				if (Current_key_down == 0)
					return false;
				//WMC - could be more efficient, but whatever.
				if (stricmp(textify_scancode(Current_key_down), scp->data.name))
					return false;
				break;
			}
		case CHC_VERSION:
			{
				// Goober5000: I'm going to assume scripting doesn't care about SVN revision
				char buf[32];
				sprintf(buf, "%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
				if (stricmp(buf, scp->data.name))
				{
					//In case some people are lazy and say "3.7" instead of "3.7.0" or something
					if (FS_VERSION_BUILD == 0)
					{
						sprintf(buf, "%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR);
						if (stricmp(buf, scp->data.name))
							return false;
					}
					else
					{
						return false;
					}
				}
				break;
			}
		case CHC_APPLICATION:
			{
				if (Fred_running)
				{
					if (stricmp("FRED2_Open", scp->data.name) && stricmp("FRED2_Open", scp->data.name) &&
						stricmp("FRED 2", scp->data.name) && stricmp("FRED", scp->data.name))
						return false;
				}
				else
				{
					if (stricmp("FS2_Open", scp->data.name) && stricmp("FS2Open", scp->data.name) &&
						stricmp("Freespace 2", scp->data.name) && stricmp("Freespace", scp->data.name))
						return false;
				}
			}
		default:
			break;
		}
	}

	return true;
}
Exemple #14
0
// init the Popup window
int popup_init(popup_info *pi, int flags)
{
	int					i;
	UI_BUTTON			*b;
	popup_background	*pbg;
	char					*fname;
	int state, choice;
	
	// to have those cool holo projection popups we need to find what
	// state the game is then load the appropiate popup graphic for
	// display
	state = gameseq_get_state();

	choice = pi->nchoices - 2;
			if (choice < 0)
				choice = 0;
	//pbg = &Popup_background[gr_screen.res][0][POPUP_DEFAULT];


	switch (state)
	{
	case GS_STATE_INITIAL_PLAYER_SELECT:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_REGDESK];
			
		break;
	case GS_STATE_MAIN_MENU:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_CONCOURSE];

		break;
	case GS_STATE_SIMULATOR_ROOM:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_LOADMISSION];

		break;
	case GS_STATE_PILOT_MANAGE:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_PILOTMANAGE];

		break;

	case GS_STATE_VIEW_CUTSCENES:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_FILMROOM];

		break;

	case GS_STATE_GAME_PLAY:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_FLY];

		break;

	/*case GS_STATE_MULTI_DOGFIGHT_DEBRIEF:
	case GS_STATE_MULTI_JOIN_GAME:
	case GS_STATE_DEBRIEF:
		pbg = &Popup_background[gr_screen.res][choice][POPUP_DEFAULT];

		break;*/
	
	default:
			pbg = &Popup_background[gr_screen.res][choice][POPUP_DEFAULT];

	}
		// anytime in single player, and multiplayer, not in mission, go ahead and stop time
	if ( (Game_mode & GM_NORMAL) || ((Game_mode && GM_MULTIPLAYER) && !(Game_mode & GM_IN_MISSION)) ){
		game_stop_time();
	}
	
	// create base window
	Popup_window.create(pbg->coords[0], pbg->coords[1], Popup_text_coords[gr_screen.res][2]+100, Popup_text_coords[gr_screen.res][3]+50, 0);
	Popup_window.set_foreground_bmap(pbg->filename);

	// create buttons
	for (i=0; i<pi->nchoices; i++) {
		b = &Popup_buttons[i];
		// accommodate single-choice positive icon being positioned differently
		if ( (pi->nchoices == 1) && (flags&PF_USE_AFFIRMATIVE_ICON) ) {
			b->create(&Popup_window, "", Button_coords[gr_screen.res][i+1][0], Button_coords[gr_screen.res][i+1][1], 30, 25, 0, 1);
		} else {
			b->create(&Popup_window, "", Button_coords[gr_screen.res][i][0], Button_coords[gr_screen.res][i][1], 30, 25, 0, 1);
		}

		fname = popup_get_button_filename(pi, i, flags);
		b->set_bmaps(fname, 3, 0);
		b->set_highlight_action(common_play_highlight_sound);
		if ( pi->keypress[i] >= 0 ) {
			b->set_hotkey(pi->keypress[i]);
		}

		// create invisible buttons to detect mouse presses... can't use mask since button region is dynamically sized
		int lx, w, h;

		gr_get_string_size(&w, &h, pi->button_text[i]);
		lx = Button_regions[gr_screen.res][i][0] - w;
		b = &Popup_button_regions[i];	

		// accommodate single-choice positive icon being positioned differently
		if ( (pi->nchoices == 1) && (flags&PF_USE_AFFIRMATIVE_ICON) ) {
			b->create(&Popup_window, "", lx, Button_regions[gr_screen.res][i+1][1], Button_regions[gr_screen.res][i+1][2]-lx, Button_regions[gr_screen.res][i+1][3]-Button_regions[gr_screen.res][i+1][1], 0, 1);
		} else {
			b->create(&Popup_window, "", lx, Button_regions[gr_screen.res][i][1], Button_regions[gr_screen.res][i][2]-lx, Button_regions[gr_screen.res][i][3]-Button_regions[gr_screen.res][i][1], 0, 1);
		}

		b->hide();
	}

	// webcursor setup
	if (Web_cursor_bitmap >= 0) {
		if (flags & PF_WEB_CURSOR_1) {
			Popup_buttons[1].set_custom_cursor_bmap(Web_cursor_bitmap);
		}
		if (flags & PF_WEB_CURSOR_2) {
			Popup_buttons[2].set_custom_cursor_bmap(Web_cursor_bitmap);
		}
	}

	// if this is an input popup, create and center the popup
	if(flags & PF_INPUT){
		Popup_input.create(&Popup_window, Popup_text_coords[gr_screen.res][0], pbg->coords[1] + Popup_input_y_offset[gr_screen.res], Popup_text_coords[gr_screen.res][2], pi->max_input_text_len, "", UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_ESC_CLR | UI_INPUTBOX_FLAG_ESC_FOC | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_TEXT_CEN);
		Popup_input.set_focus();
	}	
	
	Popup_default_choice=0;
	Popup_should_die = 0;

	if (flags & PF_RUN_STATE) {
		Popup_running_state = 1;
	} else {
		Popup_running_state = 0;
	}

	popup_split_lines(pi, flags);

	// create the popup slider (which we may not need to use
	Popup_slider.create(&Popup_window, Popup_slider_coords[gr_screen.res][0], Popup_slider_coords[gr_screen.res][1], Popup_slider_coords[gr_screen.res][2], Popup_slider_coords[gr_screen.res][3], pi->nlines > Popup_max_display[gr_screen.res] ? pi->nlines - Popup_max_display[gr_screen.res] : 0,
								Popup_slider_name[gr_screen.res], popup_slider_bogus, popup_slider_bogus, NULL);

	return 0;
}
bool ConditionedHook::ConditionsValid(int action, object *objp, int more_data)
{
	uint i;

	//Return false if any conditions are not met
	script_condition *scp;
	ship_info *sip;
	for(i = 0; i < MAX_HOOK_CONDITIONS; i++)
	{
		scp = &Conditions[i];
		switch(scp->condition_type)
		{
			case CHC_STATE:
				if(gameseq_get_depth() < 0)
					return false;
				if(stricmp(GS_state_text[gameseq_get_state(0)], scp->data.name))
					return false;
				break;
			case CHC_SHIPTYPE:
				if(objp == NULL || objp->type != OBJ_SHIP)
					return false;
				sip = &Ship_info[Ships[objp->instance].ship_info_index];
				if(sip->class_type < 0)
					return false;
				if(stricmp(Ship_types[sip->class_type].name, scp->data.name))
					return false;
			case CHC_SHIPCLASS:
				if(objp == NULL || objp->type != OBJ_SHIP)
					return false;
				if(stricmp(Ship_info[Ships[objp->instance].ship_info_index].name, scp->data.name))
					return false;
				break;
			case CHC_SHIP:
				if(objp == NULL || objp->type != OBJ_SHIP)
					return false;
				if(stricmp(Ships[objp->instance].ship_name, scp->data.name))
					return false;
				break;
			case CHC_MISSION:
				{
					//WMC - Get mission filename with Mission_filename
					//I don't use Game_current_mission_filename, because
					//Mission_filename is valid in both fs2_open and FRED
					size_t len = strlen(Mission_filename);
					if(!len)
						return false;
					if(len > 4 && !stricmp(&Mission_filename[len-4], ".fs2"))
						len -= 4;
					if(strnicmp(scp->data.name, Mission_filename, len))
						return false;
					break;
				}
			case CHC_CAMPAIGN:
				{
					size_t len = strlen(Campaign.filename);
					if(!len)
						return false;
					if(len > 4 && !stricmp(&Mission_filename[len-4], ".fc2"))
						len -= 4;
					if(strnicmp(scp->data.name, Mission_filename, len))
						return false;
					break;
				}
			case CHC_WEAPONCLASS:
				{
					if (action == CHA_COLLIDEWEAPON) {
						if (stricmp(Weapon_info[more_data].name, scp->data.name) != 0)
							return false;
					} else if (!(action == CHA_ONWPSELECTED || action == CHA_ONWPDESELECTED || action == CHA_ONWPEQUIPPED || action == CHA_ONWPFIRED || action == CHA_ONTURRETFIRED )) {
						if(objp == NULL || (objp->type != OBJ_WEAPON && objp->type != OBJ_BEAM))
							return false;
						else if (( objp->type == OBJ_WEAPON) && (stricmp(Weapon_info[Weapons[objp->instance].weapon_info_index].name, scp->data.name) != 0 ))
							return false;
						else if (( objp->type == OBJ_BEAM) && (stricmp(Weapon_info[Beams[objp->instance].weapon_info_index].name, scp->data.name) != 0 ))
							return false;
					} else if(objp == NULL || objp->type != OBJ_SHIP) {
						return false;
					} else {

						// Okay, if we're still here, then objp is both valid and a ship
						ship* shipp = &Ships[objp->instance];
						bool primary = false, secondary = false, prev_primary = false, prev_secondary = false;
						switch (action) {
							case CHA_ONWPSELECTED:
								primary = stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name, scp->data.name) == 0;
								secondary = stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name, scp->data.name) == 0;
								
								if (!(primary || secondary))
									return false;

								if ((shipp->flags[Ship::Ship_Flags::Primary_linked]) && primary && (Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].wi_flags[Weapon::Info_Flags::Nolink]))
									return false;
								
								break;
							case CHA_ONWPDESELECTED:
								primary = stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name, scp->data.name) == 0;
								prev_primary = stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.previous_primary_bank]].name, scp->data.name) == 0;
								secondary = stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name, scp->data.name) == 0;
								prev_secondary = stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.previous_secondary_bank]].name, scp->data.name) == 0;

								if ((shipp->flags[Ship::Ship_Flags::Primary_linked]) && prev_primary && (Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.previous_primary_bank]].wi_flags[Weapon::Info_Flags::Nolink]))
									return true;

								if ( !prev_secondary && ! secondary && !prev_primary && !primary )
									return false;

								if ( (!prev_secondary && !secondary) && (prev_primary && primary) ) 
									return false;

								if ( (!prev_secondary && !secondary) && (!prev_primary && primary) ) 
									return false;

								if ( (!prev_primary && !primary) && (prev_secondary && secondary) )
									return false;

								if ( (!prev_primary && !primary) && (!prev_secondary && secondary) )
									return false;

								break;
							case CHA_ONWPEQUIPPED: {
								bool equipped = false;
								for(int j = 0; j < MAX_SHIP_PRIMARY_BANKS; j++) {
									if (!equipped && (shipp->weapons.primary_bank_weapons[j] >= 0) && (shipp->weapons.primary_bank_weapons[j] < MAX_WEAPON_TYPES) ) {
										if ( !stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[j]].name, scp->data.name) ) {
											equipped = true;
											break;
										}
									}
								}
							
								if (!equipped) {
									for(int j = 0; j < MAX_SHIP_SECONDARY_BANKS; j++) {
										if (!equipped && (shipp->weapons.secondary_bank_weapons[j] >= 0) && (shipp->weapons.secondary_bank_weapons[j] < MAX_WEAPON_TYPES) ) {
											if ( !stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[j]].name, scp->data.name) ) {
												equipped = true;
												break;
											}
										}
									}
								}

								if (!equipped)
									return false;
							
								break;
							}
							case CHA_ONWPFIRED: {
								if (more_data == 1) {
									primary = stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name, scp->data.name) == 0;
									secondary = false;
								} else {
									primary = false;
									secondary = stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name, scp->data.name) == 0;
								}

								if ((shipp->flags[Ship::Ship_Flags::Primary_linked]) && primary && (Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].wi_flags[Weapon::Info_Flags::Nolink]))
								 	return false;

								return more_data == 1 ? primary : secondary;

								break;
							}
							case CHA_ONTURRETFIRED: {
								if (! (stricmp(Weapon_info[shipp->last_fired_turret->last_fired_weapon_info_index].name, scp->data.name) == 0))
									return false;
								break;
							}
							case CHA_PRIMARYFIRE: {
								if (stricmp(Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name, scp->data.name))
									return false;
								break;
							}
							case CHA_SECONDARYFIRE: {
								if (stricmp(Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name, scp->data.name))
									return false;
								break;
							}
							case CHA_BEAMFIRE: {
								if (!(stricmp(Weapon_info[more_data].name, scp->data.name) == 0))
									return false;
								break;
							}

						}
					} // case CHC_WEAPONCLASS
					break;
				}
			case CHC_OBJECTTYPE:
				if(objp == NULL)
					return false;
				if(stricmp(Object_type_names[objp->type], scp->data.name))
					return false;
				break;
			case CHC_KEYPRESS:
				{
					extern int Current_key_down;
					if(gameseq_get_depth() < 0)
						return false;
					if(Current_key_down == 0)
						return false;
					//WMC - could be more efficient, but whatever.
					if(stricmp(textify_scancode(Current_key_down), scp->data.name))
						return false;
					break;
				}
			case CHC_ACTION:
				{
					if(gameseq_get_depth() < 0)
						return false;

					int action_index = more_data;

					if (action_index <= 0 || stricmp(scp->data.name, Control_config[action_index].text))
						return false;
					break;
				}
			case CHC_VERSION:
				{
					// Goober5000: I'm going to assume scripting doesn't care about SVN revision
					char buf[32];
					sprintf(buf, "%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
					if(stricmp(buf, scp->data.name))
					{
						//In case some people are lazy and say "3.7" instead of "3.7.0" or something
						if(FS_VERSION_BUILD == 0)
						{
							sprintf(buf, "%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR);
							if(stricmp(buf, scp->data.name))
								return false;
						}
						else
						{
							return false;
						}
					}
					break;
				}
			case CHC_APPLICATION:
				{
					if(Fred_running)
					{
						if(stricmp("FRED2_Open", scp->data.name) && stricmp("FRED2Open", scp->data.name) && stricmp("FRED 2", scp->data.name) && stricmp("FRED", scp->data.name))
							return false;
					}
					else
					{
						if(stricmp("FS2_Open", scp->data.name) && stricmp("FS2Open", scp->data.name) && stricmp("Freespace 2", scp->data.name) && stricmp("Freespace", scp->data.name))
							return false;
					}
				}
			default:
				break;
		}
	}

	return true;
}