コード例 #1
0
ファイル: multi_respawn.cpp プロジェクト: lubomyr/freespace2
// process an incoming respawn info packet
void multi_respawn_process_packet(ubyte *data, header *hinfo)
{
	ubyte code,cur_link_status;
	char cur_primary_bank,cur_secondary_bank;
	ushort net_sig,ship_ets;
	short player_id;
	int player_index;
	vector v;	
	char parse_name[1024] = "";
	int offset = HEADER_LENGTH;

	// determine who send the packet	
	player_index = find_player_id(hinfo->id);
	if(player_index == -1){
		nprintf(("Network","Couldn't find player for processing respawn packet!\n"));
	}

	// get the opcode
	GET_DATA(code);

	// do something based upon the opcode
	switch((int)code){

	case AI_RESPAWN_NOTICE: 
		p_object *pobjp;

		GET_USHORT( net_sig );
		pobjp = mission_parse_get_arrival_ship( net_sig );
		Assert( pobjp != NULL );
		multi_respawn_ai( pobjp );
		break;		

	case RESPAWN_BROADCAST:
		// get the respawn data
		GET_USHORT(net_sig);
		get_vector_data( data, &offset, v );
		GET_SHORT(player_id);
		GET_DATA(cur_primary_bank);
		GET_DATA(cur_secondary_bank);
		GET_DATA(cur_link_status);
		GET_USHORT(ship_ets);
		GET_STRING(parse_name);
		player_index = find_player_id(player_id);
		if(player_index == -1){
			nprintf(("Network","Couldn't find player to respawn!\n"));
			break;
		}

		// create the ship and assign its position, net_signature, and class
		// respawn the player
		multi_respawn_player(&Net_players[player_index], cur_primary_bank, cur_secondary_bank, cur_link_status, ship_ets, net_sig, parse_name, &v);

		// if this is for me, I should jump back into gameplay
		if(&Net_players[player_index] == Net_player){
			extern int Player_multi_died_check;
			Player_multi_died_check = -1;

			gameseq_post_event(GS_EVENT_ENTER_GAME);
		}
		break;
	
	case RESPAWN_REQUEST:
		// determine whether he wants to respawn as an observer or not
		GET_DATA(code);

		nprintf(("Network","Received respawn request\n"));
		if(player_index == -1){
			nprintf(("Network","Received respawn request from unknown player!\n"));
			break;
		} 		     		

		// make sure he's not making an invalid request
		if((code == 0) && !(Net_players[player_index].flags & NETINFO_FLAG_RESPAWNING)){
			nprintf(("Network","Received respawn request from player who shouldn't be respawning!\n"));
			Int3();
			break;
		} else if((code == 1) && !(Net_players[player_index].flags & NETINFO_FLAG_LIMBO)){
			nprintf(("Network","Received respawn observer request from a player who shouldn't be respawning as an observer!\n"));
			Int3();
			break;
		}

		// otherwise perform the operation
		// respawn the guy as an observer
		if(code){
			multi_respawn_make_observer(&Net_players[player_index]);			
		}
		// respawn him as normal
		else {						
			// create his new ship, and change him from respawning to respawned
			Assert(Net_players[player_index].p_info.p_objp != NULL);
			if(Net_players[player_index].p_info.p_objp != NULL){
				multi_respawn_player(&Net_players[player_index], Net_players[player_index].s_info.cur_primary_bank, Net_players[player_index].s_info.cur_secondary_bank,Net_players[player_index].s_info.cur_link_status, Net_players[player_index].s_info.ship_ets, 0, Net_players[player_index].p_info.p_objp->name);
			}			
		}	
		break;
	}

	PACKET_SET_SIZE();
}
コード例 #2
0
ファイル: multi_respawn.cpp プロジェクト: lubomyr/freespace2
// check to see if a net player needs to be respawned
void multi_respawn_check(object *objp)
{
	int player_index;
	net_player *pl = NULL;
	p_object *pobjp;

	// get the parse object since we are storing all data for the respawns in the parse object
	pobjp = mission_parse_get_arrival_ship( objp->net_signature );
	
	// the server should check against all players
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		player_index = multi_find_player_by_object(objp);
		if(player_index != -1){
			pl = &Net_players[player_index];
		}
	}
	// clients should just check against themselves
	else if(objp == Player_obj){
		pl = Net_player;		
	}	

	// if this ship isn't a player ship, then maybe it is an AI ship which should get respawed.  Only respawn
	// on the server, then send message to respawn on client.
	if( pl == NULL ) {

		// try and find the parse object with this net signature.  If we found it, and it's a player start
		// position, respawn it.
		if ( Net_player->flags & NETINFO_FLAG_AM_MASTER ) {
			if ( !pobjp ){
				return;
			}

			// if we need to respawn this ai ship, add him to a list of ships to get respawned
			if ( (pobjp->flags & P_OF_PLAYER_START) && (pobjp->respawn_count < Netgame.respawn) && !(Netgame.type_flags & NG_TYPE_DOGFIGHT) ){
				int i;

				for (i = 0; i < MAX_AI_RESPAWNS; i++ ) {
					if ( Ai_respawns[i].pobjp == NULL ) {
						Ai_respawns[i].pobjp = pobjp;
						Ai_respawns[i].timestamp = timestamp(AI_RESPAWN_TIME);
						break;
					}
				}
				Assert( i < MAX_AI_RESPAWNS );
			}
		}

		return;
	} else {
		// reset his datarate timestamp
		extern int OO_gran;
		pl->s_info.rate_stamp = timestamp( (int)(1000.0f / (float)OO_gran) );
	}

	Assert( pl != NULL );
	Assert( pobjp );				// we have a player, and we should have a record of it.
	
	// mark the player as in the state of respawning
	if( (pobjp->respawn_count < Netgame.respawn) || (Netgame.type_flags & NG_TYPE_DOGFIGHT) ){
		pl->flags |= NETINFO_FLAG_RESPAWNING;
	}
	// otherwise mark the player as being in limbo
	else {
		pl->flags |= NETINFO_FLAG_LIMBO;
	}
}
コード例 #3
0
ファイル: multi_respawn.cpp プロジェクト: lubomyr/freespace2
// respawn the passed player with the passed ship object and weapon link settings
void multi_respawn_player(net_player *pl, char cur_primary_bank, char cur_secondary_bank, ubyte cur_link_status, ushort ship_ets, ushort net_sig, char *parse_name, vector *pos)
{
	int objnum;
	object *objp;
	ship *shipp;
	p_object *pobjp;	

	// try and find the parse object
	pobjp = mission_parse_get_arrival_ship(parse_name);		
	Assert(pobjp != NULL);
	if(pobjp == NULL){
		return;
	}
	objnum = multi_respawn_common_stuff(pobjp);

	Assert( objnum != -1 );
	objp = &Objects[objnum];
	shipp = &Ships[objp->instance];	

	// this is a player, so mark him as a player,
	objp->flags |= OF_PLAYER_SHIP;
	objp->flags &= ~OF_COULD_BE_PLAYER;

	// server should mark this player as invulerable for a short time
	if ( MULTIPLAYER_MASTER ) {
		objp->flags |= OF_INVULNERABLE;
		pl->s_info.invul_timestamp = timestamp(RESPAWN_INVUL_TIMESTAMP); 					
		multi_respawn_place( objp, shipp->team );
	}

	// reset his datarate timestamp
	extern int OO_gran;
	pl->s_info.rate_stamp = timestamp( (int)(1000.0f / (float)OO_gran) );

	// set some player information
	pl->player->objnum = objnum;
	if ( pl == Net_player ) {
		// this is a hack to ensure that old (dead) player ships are destroyed, since at this point he's actually an OBJ_GHOST
		Player_obj->flags |= OF_SHOULD_BE_DEAD;						
		obj_delete(OBJ_INDEX(Player_obj));	
		
		Player_obj = objp;
		Player_ship = shipp;
		Player_ai = &Ai_info[Player_ship->ai_index];

		//	get rid of the annoying HUD dead message text.
		HUD_init_fixed_text();
	}	

	// clients bash net signature
	if(!(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
		objp->net_signature = net_sig;
	}
	
	// restore the correct weapon bank selections
	shipp->weapons.current_primary_bank = (int)cur_primary_bank;
	shipp->weapons.current_secondary_bank = (int)cur_secondary_bank;
	if(cur_link_status & (1<<0)){
		shipp->flags |= SF_PRIMARY_LINKED;
	} else {
		shipp->flags &= ~(SF_PRIMARY_LINKED);
	}			
	if(cur_link_status & (1<<1)){
		shipp->flags |= SF_SECONDARY_DUAL_FIRE;
	} else {
		shipp->flags &= ~(SF_SECONDARY_DUAL_FIRE);
	}

	Assert( ship_ets != 0 );		// find dave or allender

	// restore the correct ets settings
	shipp->shield_recharge_index = ((ship_ets & 0x0f00) >> 8);
	// weapon ets
	shipp->weapon_recharge_index = ((ship_ets & 0x00f0) >> 4);
	// engine ets
	shipp->engine_recharge_index = (ship_ets & 0x000f);

	// if this is a dogfight mission, make him TEAM_TRAITOR
	if(Netgame.type_flags & NG_TYPE_DOGFIGHT){
		shipp->team = TEAM_TRAITOR;
	}

	// maybe bash ship position
	if(pos != NULL){
		objp->pos = *pos;
	}

	// unset his respawning flag
	pl->flags &= ~(NETINFO_FLAG_RESPAWNING | NETINFO_FLAG_LIMBO);

	// blast his control and button info clear
	memset(&pl->player->bi, 0, sizeof(pl->player->bi));
	memset(&pl->player->ci, 0, sizeof(pl->player->ci));

	// if this is me, clear accum button info
	if(pl == Net_player){
		// clear multiplayer button info			
		extern button_info Multi_ship_status_bi;
		memset(&Multi_ship_status_bi, 0, sizeof(button_info));
	}

	// notify other players of the respawn
	if ( MULTIPLAYER_MASTER ){
		multi_respawn_broadcast(pl);
	}
}
コード例 #4
0
// respawn the passed player with the passed ship object and weapon link settings
void multi_respawn_player(net_player *pl, char cur_primary_bank, char cur_secondary_bank, ubyte cur_link_status, ushort ship_ets, ushort net_sig, char *parse_name, vec3d *pos)
{
	int objnum;
	object *objp;
	ship *shipp;
	p_object *pobjp;	

	// try and find the parse object
	pobjp = mission_parse_get_arrival_ship(parse_name);		
	Assert(pobjp != NULL);
	if(pobjp == NULL){
		return;
	}
	objnum = multi_respawn_common_stuff(pobjp);

	Assert( objnum != -1 );
	objp = &Objects[objnum];
	shipp = &Ships[objp->instance];	

	// this is a player, so mark him as a player,
    objp->flags.set(Object::Object_Flags::Player_ship);
    objp->flags.remove(Object::Object_Flags::Could_be_player);

	// server should mark this player as invulerable for a short time
	if ( MULTIPLAYER_MASTER ) {
        objp->flags.set(Object::Object_Flags::Invulnerable);
		pl->s_info.invul_timestamp = timestamp(RESPAWN_INVUL_TIMESTAMP); 					
		multi_respawn_place( objp, shipp->team );
	}

	// reset his datarate timestamp
	extern int OO_gran;
	pl->s_info.rate_stamp = timestamp( (int)(1000.0f / (float)OO_gran) );

	// set some player information
	pl->m_player->objnum = objnum;
	if ( pl == Net_player ) {
		object *oldplr = Player_obj;

		Player_obj = objp;
		Player_ship = shipp;
		Player_ai = &Ai_info[Player_ship->ai_index];

		// this is a hack to ensure that old (dead) player ships are destroyed, since at this point he's actually an OBJ_GHOST
        oldplr->flags.set(Object::Object_Flags::Should_be_dead);
		obj_delete(OBJ_INDEX(oldplr));	

		//	get rid of the annoying HUD dead message text.
		HUD_init_fixed_text();
	}	

	// clients bash net signature
	if(!(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
		objp->net_signature = net_sig;
	}
	
	// restore the correct weapon bank selections
	shipp->weapons.current_primary_bank = (int)cur_primary_bank;
	shipp->weapons.current_secondary_bank = (int)cur_secondary_bank;
	if(cur_link_status & (1<<0)){
		shipp->flags.set(Ship::Ship_Flags::Primary_linked);
	} else {
        shipp->flags.remove(Ship::Ship_Flags::Primary_linked);
	}			
	if(cur_link_status & (1<<1)){
		shipp->flags.set(Ship::Ship_Flags::Secondary_dual_fire);
    }
    else {
        shipp->flags.remove(Ship::Ship_Flags::Secondary_dual_fire);
    }

	Assert( ship_ets != 0 );		// find dave or allender

	// restore the correct ets settings
	shipp->shield_recharge_index = ((ship_ets & 0x0f00) >> 8);
	// weapon ets
	shipp->weapon_recharge_index = ((ship_ets & 0x00f0) >> 4);
	// engine ets
	shipp->engine_recharge_index = (ship_ets & 0x000f);

	// give the current bank a half-second timestamp so that we don't fire immediately unpon respawn
	shipp->weapons.next_secondary_fire_stamp[shipp->weapons.current_secondary_bank] = timestamp(500);

	// if this is a dogfight mission, make him TEAM_TRAITOR
	if(Netgame.type_flags & NG_TYPE_DOGFIGHT){
		shipp->team = Iff_traitor;
	}

	// maybe bash ship position
	if(pos != NULL){
		objp->pos = *pos;
	}

	// unset his respawning flag
	pl->flags &= ~(NETINFO_FLAG_RESPAWNING | NETINFO_FLAG_LIMBO);

	// blast his control and button info clear
	memset(&pl->m_player->bi, 0, sizeof(pl->m_player->bi));
	memset(&pl->m_player->ci, 0, sizeof(pl->m_player->ci));

	// set throttle based on initial velocity specified in mission (the vel gets calculated
	//   like a percentage of our max speed, so we can just use it as-is for the throttle)
	pl->m_player->ci.forward_cruise_percent = (float)pobjp->initial_velocity;
	CLAMP(pl->m_player->ci.forward_cruise_percent, 0.0f, 100.0f);

	// if this is me, clear accum button info
	if(pl == Net_player){
		// clear multiplayer button info			
		extern button_info Multi_ship_status_bi;
		memset(&Multi_ship_status_bi, 0, sizeof(button_info));
	}

	// notify other players of the respawn
	if ( MULTIPLAYER_MASTER ){
		multi_respawn_broadcast(pl);
	}
}