//initialize the player object position & orientation (at start of game, or new ship) void InitPlayerPosition(int random) { int NewPlayer=0; if (! ((Game_mode & GM_MULTI) && !(Game_mode&GM_MULTI_COOP)) ) // If not deathmatch NewPlayer = Player_num; #ifdef NETWORK else if ((Game_mode & GM_MULTI) && (Netgame.SpawnStyle == SPAWN_STYLE_PREVIEW) && Dead_player_camera != NULL) NewPlayer = previewed_spawn_point; #endif else if (random == 1) { int i, trys=0; fix closest_dist = 0x7ffffff, dist; timer_update(); d_srand((fix)timer_query()); do { trys++; NewPlayer = d_rand() % NumNetPlayerPositions; closest_dist = 0x7fffffff; for (i=0; i<N_players; i++ ) { if ( (i!=Player_num) && (Objects[Players[i].objnum].type == OBJ_PLAYER) ) { dist = find_connected_distance(&Objects[Players[i].objnum].pos, Objects[Players[i].objnum].segnum, &Player_init[NewPlayer].pos, Player_init[NewPlayer].segnum, 15, WID_FLY_FLAG ); // Used to be 5, search up to 15 segments if ( (dist < closest_dist) && (dist >= 0) ) { closest_dist = dist; } } } } while ( (closest_dist<i2f(15*20)) && (trys<MAX_PLAYERS*2) ); } else { // If deathmatch and not random, positions were already determined by sync packet reset_player_object(); reset_cruise(); return; } Assert(NewPlayer >= 0); Assert(NewPlayer < NumNetPlayerPositions); ConsoleObject->pos = Player_init[NewPlayer].pos; ConsoleObject->orient = Player_init[NewPlayer].orient; #ifdef NETWORK if ((Game_mode & GM_MULTI) && (Netgame.SpawnStyle == SPAWN_STYLE_PREVIEW) && Dead_player_camera != NULL) { ConsoleObject->orient = Dead_player_camera->orient; Dead_player_camera = NULL; } #endif obj_relink(ConsoleObject-Objects,Player_init[NewPlayer].segnum); reset_player_object(); reset_cruise(); }
int NetworkStartGame (void) { int i, bAutoRun; if (gameStates.multi.nGameType >= IPX_GAME) { Assert (FRAME_INFO_SIZE < DATALIMIT); if (!networkData.bActive) { ExecMessageBox (NULL, NULL, 1, TXT_OK, TXT_IPX_NOT_FOUND); return 0; } } NetworkInit (); ChangePlayerNumTo (0); if (NetworkFindGame ()) { ExecMessageBox (NULL, NULL, 1, TXT_OK, TXT_NET_FULL); return 0; } bAutoRun = InitAutoNetGame (); if (0 > (i = NetworkGetGameParams (bAutoRun))) return 0; gameData.multiplayer.nPlayers = 0; netGame.difficulty = gameStates.app.nDifficultyLevel; netGame.gameMode = mpParams.nGameMode; netGame.gameStatus = NETSTAT_STARTING; netGame.nNumPlayers = 0; netGame.nMaxPlayers = gameData.multiplayer.nMaxPlayers; netGame.nLevel = mpParams.nLevel; netGame.protocolVersion = MULTI_PROTO_VERSION; strcpy (netGame.szGameName, mpParams.szGameName); networkData.nStatus = NETSTAT_STARTING; // Have the network driver initialize whatever data it wants to // store for this netgame. // For mcast4, this randomly chooses a multicast session and port. // Clients subscribe to this address when they call // IpxHandleNetGameAuxData. IpxInitNetGameAuxData (netGame.AuxData); NetworkSetGameMode (netGame.gameMode); d_srand (TimerGetFixedSeconds ()); netGame.nSecurity = d_rand (); // For syncing Netgames with tPlayer packets if (NetworkSelectPlayers (bAutoRun)) { StartNewLevel (netGame.nLevel, 0); ResetAllPlayerTimeouts (); return 1; } else { gameData.app.nGameMode = GM_GAME_OVER; return 0; } }
//initialize the player object position & orientation (at start of game, or new ship) void InitPlayerPosition(int random) { int NewPlayer=0; if (! ((Game_mode & GM_MULTI) && !(Game_mode&GM_MULTI_COOP)) ) // If not deathmatch NewPlayer = Player_num; #ifdef NETWORK else if (random == 1) { int i, closest = -1, trys=0; fix closest_dist = 0x7ffffff, dist; d_srand(clock()); do { trys++; NewPlayer = d_rand() % NumNetPlayerPositions; closest = -1; closest_dist = 0x7fffffff; for (i=0; i<N_players; i++ ) { if ( (i!=Player_num) && (Objects[Players[i].objnum].type == OBJ_PLAYER) ) { dist = find_connected_distance(&Objects[Players[i].objnum].pos, Objects[Players[i].objnum].segnum, &Player_init[NewPlayer].pos, Player_init[NewPlayer].segnum, 5, WID_FLY_FLAG ); if ( (dist < closest_dist) && (dist >= 0) ) { closest_dist = dist; closest = i; } } } } while ( (closest_dist<i2f(10*20)) && (trys<MAX_NUM_NET_PLAYERS*2) ); } #endif else { goto done; // If deathmatch and not random, positions were already determined by sync packet } Assert(NewPlayer >= 0); Assert(NewPlayer < NumNetPlayerPositions); ConsoleObject->pos = Player_init[NewPlayer].pos; ConsoleObject->orient = Player_init[NewPlayer].orient; obj_relink(ConsoleObject-Objects,Player_init[NewPlayer].segnum); done: reset_player_object(); reset_cruise(); }
void NetworkSendSync (void) { int i, j, np; // Randomize their starting locations... d_srand (TimerGetFixedSeconds ()); for (i = 0; i < gameData.multiplayer.nPlayerPositions; i++) { if (gameData.multiplayer.players [i].connected) gameData.multiplayer.players [i].connected = 1; // Get rid of endlevel connect statuses if (IsCoopGame) netGame.locations [i] = i; else { do { np = d_rand () % gameData.multiplayer.nPlayerPositions; for (j = 0; j < i; j++) { if (netGame.locations [j] == np) { np = -1; break; } } } while (np < 0); // np is a location that is not used anywhere else.. netGame.locations [i] = np; } } // Push current data into the sync packet NetworkUpdateNetGame (); netGame.gameStatus = NETSTAT_PLAYING; netGame.nType = PID_SYNC; netGame.nSegmentCheckSum = networkData.nSegmentCheckSum; for (i = 0; i < gameData.multiplayer.nPlayers; i++) { if ((!gameData.multiplayer.players [i].connected) || (i == gameData.multiplayer.nLocalPlayer)) continue; if (gameStates.multi.nGameType >= IPX_GAME) { // Send several times, extras will be ignored SendInternetFullNetGamePacket ( netPlayers.players [i].network.ipx.server, netPlayers.players [i].network.ipx.node); SendNetPlayersPacket ( netPlayers.players [i].network.ipx.server, netPlayers.players [i].network.ipx.node); } } NetworkReadSyncPacket (&netGame, 1); // Read it myself, as if I had sent it }
void NetworkSendSync (void) { int i; d_srand (gameStates.app.nRandSeed = TimerGetFixedSeconds ()); // Randomize their starting locations... for (i = 0; i < gameData.multiplayer.nPlayerPositions; i++) if (gameData.multiplayer.players [i].connected) gameData.multiplayer.players [i].connected = 1; // Get rid of endlevel connect statuses if (IsCoopGame) { for (i = 0; i < gameData.multiplayer.nPlayerPositions; i++) *netGame.Locations (i) = i; } else { // randomize player positions int h, j = gameData.multiplayer.nPlayerPositions, posTable [MAX_PLAYERS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15}; for (i = 0; i < gameData.multiplayer.nPlayerPositions; i++) { h = d_rand () % j; // compute random table index *netGame.Locations (i) = posTable [h]; // pick position using random index if (h < --j) posTable [h] = posTable [j]; // remove picked position from position table } } // Push current data into the sync packet NetworkUpdateNetGame (); netGame.m_info.gameStatus = NETSTAT_PLAYING; netGame.m_info.nType = PID_SYNC; netGame.SetSegmentCheckSum (networkData.nSegmentCheckSum); for (i = 0; i < gameData.multiplayer.nPlayers; i++) { if ((!gameData.multiplayer.players [i].connected) || (i == gameData.multiplayer.nLocalPlayer)) continue; if (gameStates.multi.nGameType >= IPX_GAME) { // Send several times, extras will be ignored SendInternetFullNetGamePacket (netPlayers.m_info.players [i].network.ipx.server, netPlayers.m_info.players [i].network.ipx.node); SendNetPlayersPacket (netPlayers.m_info.players [i].network.ipx.server, netPlayers.m_info.players [i].network.ipx.node); } } NetworkProcessSyncPacket (&netGame, 1); // Read it myself, as if I had sent it }
//this function is for when the player intentionally drops a powerup //this function is based on drop_powerup() objnum_t spit_powerup(dxxobject *spitter, int id,int seed) { objnum_t objnum; dxxobject *obj; vms_vector new_velocity, new_pos; d_srand(seed); vm_vec_scale_add(&new_velocity,&spitter->mtype.phys_info.velocity,&spitter->orient.fvec,i2f(SPIT_SPEED)); new_velocity.x += (d_rand() - 16384) * SPIT_SPEED * 2; new_velocity.y += (d_rand() - 16384) * SPIT_SPEED * 2; new_velocity.z += (d_rand() - 16384) * SPIT_SPEED * 2; // Give keys zero velocity so they can be tracked better in multi if ((Game_mode & GM_MULTI) && (id >= POW_KEY_BLUE) && (id <= POW_KEY_GOLD)) vm_vec_zero(&new_velocity); //there's a piece of code which lets the player pick up a powerup if //the distance between him and the powerup is less than 2 time their //combined radii. So we need to create powerups pretty far out from //the player. vm_vec_scale_add(&new_pos,&spitter->pos,&spitter->orient.fvec,spitter->size); #ifdef NETWORK if (Game_mode & GM_MULTI) { if (Net_create_loc >= MAX_NET_CREATE_OBJECTS) { return object_none; } } #endif objnum = obj_create( OBJ_POWERUP, id, spitter->segnum, &new_pos, &vmd_identity_matrix, Powerup_info[id].size, CT_POWERUP, MT_PHYSICS, RT_POWERUP); if (objnum == object_none ) { Int3(); return objnum; } obj = &Objects[objnum]; obj->mtype.phys_info.velocity = new_velocity; obj->mtype.phys_info.drag = 512; //1024; obj->mtype.phys_info.mass = F1_0; obj->mtype.phys_info.flags = PF_BOUNCE; obj->rtype.vclip_info.vclip_num = Powerup_info[obj->id].vclip_num; obj->rtype.vclip_info.frametime = Vclip[obj->rtype.vclip_info.vclip_num].frame_time; obj->rtype.vclip_info.framenum = 0; if (spitter == ConsoleObject) obj->ctype.powerup_info.flags |= PF_SPAT_BY_PLAYER; switch (obj->id) { case POW_MISSILE_1: case POW_MISSILE_4: case POW_SHIELD_BOOST: case POW_ENERGY: obj->lifeleft = (d_rand() + F1_0*3) * 64; // Lives for 3 to 3.5 binary minutes (a binary minute is 64 seconds) if (Game_mode & GM_MULTI) obj->lifeleft /= 2; break; default: //if (Game_mode & GM_MULTI) // obj->lifeleft = (d_rand() + F1_0*3) * 64; // Lives for 5 to 5.5 binary minutes (a binary minute is 64 seconds) break; } return objnum; }
//----------------------------------------------------------------------------- // Create the children of a smart bomb, which is a bunch of homing missiles. void CreateSmartChildren (CObject *objP, int nSmartChildren) { tParentInfo parent; int bMakeSound; int nObjects = 0; int objList [MAX_OBJDISTS]; ubyte nBlobId, nObjType = objP->info.nType, nObjId = objP->info.nId; if (nObjType == OBJ_WEAPON) { parent = objP->cType.laserInfo.parent; } else if (nObjType == OBJ_ROBOT) { parent.nType = OBJ_ROBOT; parent.nObject = objP->Index (); } else { Int3 (); // Hey, what kind of CObject is this!? parent.nType = 0; parent.nObject = 0; } if (nObjType == OBJ_WEAPON) { if (gameData.weapons.info [nObjId].children < 1) //if ((nObjId == SMARTMSL_ID) || (nObjId == SMARTMINE_ID) || (nObjId == ROBOT_SMARTMINE_ID) || (nObjId == EARTHSHAKER_ID)) && return; if (nObjId == EARTHSHAKER_ID) BlastNearbyGlass (objP, gameData.weapons.info [EARTHSHAKER_ID].strength [gameStates.app.nDifficultyLevel]); } else if (nObjType != OBJ_ROBOT) // && ((nObjType != OBJ_WEAPON) || (gameData.weapons.info [nObjId].children < 1))) return; int i, nObject; CObject *curObjP; if (IsMultiGame) d_srand (gameStates.app.nRandSeed = 8321L); FORALL_OBJS (curObjP, nObject) { nObject = OBJ_IDX (curObjP); if (curObjP->info.nType == OBJ_PLAYER) { if (nObject == parent.nObject) continue; if ((parent.nType == OBJ_PLAYER) && (IsCoopGame)) continue; if (IsTeamGame && (GetTeam (curObjP->info.nId) == GetTeam (OBJECTS [parent.nObject].info.nId))) continue; if (gameData.multiplayer.players [curObjP->info.nId].flags & PLAYER_FLAGS_CLOAKED) continue; } else if (curObjP->info.nType == OBJ_ROBOT) { if (curObjP->cType.aiInfo.CLOAKED) continue; if (parent.nType == OBJ_ROBOT) // Robot blobs can't track robots. continue; if ((parent.nType == OBJ_PLAYER) && ROBOTINFO (curObjP->info.nId).companion) // Your shots won't track the buddy. continue; } else continue; fix dist = CFixVector::Dist (objP->info.position.vPos, curObjP->info.position.vPos); if (dist < MAX_SMART_DISTANCE) { int oovis = ObjectToObjectVisibility (objP, curObjP, FQ_TRANSWALL); if (oovis) { //ObjectToObjectVisibility (objP, curObjP, FQ_TRANSWALL)) { objList [nObjects++] = nObject; if (nObjects >= MAX_OBJDISTS) { nObjects = MAX_OBJDISTS; break; } } } }