예제 #1
0
void Game::shootSV(int playerID, int nuzzleID, float imp, CVector3f p1, CVector3f p2)
{
	Player* player = players[playerID];
	if (player == 0)
		return;
	int ident = (int)imp;
	CVector3f oldP2;
	if(player->weapon->weaponID == WEAPON_SHOTGUN)
	{
		switch(ident)
		{
		case 1:
			oldP2 = rotateAboutAxis(p2, 10.0f, CVector3f(0.0f, 0.0f, 1.0f));
			break;
		case 2:
			oldP2 = rotateAboutAxis(p2, 5.0f, CVector3f(0.0f, 0.0f, 1.0f));
			break;
		case 3:
			oldP2 = rotateAboutAxis(p2, 0.0f, CVector3f(0.0f, 0.0f, 1.0f));
			break;
		case 4:
			oldP2 = rotateAboutAxis(p2, -5.0f, CVector3f(0.0f, 0.0f, 1.0f));
			break;
		case 5:
			oldP2 = rotateAboutAxis(p2, -10.0f, CVector3f(0.0f, 0.0f, 1.0f));
			break;
		};	
		normalize(oldP2);
	}	
	if(player->weapon->weaponID == WEAPON_SHOTGUN)
	{
		imp = 3.5f;
	}
#ifdef _PRO_
	CVector3f dir = p2;
    
	if (player->weapon->projectileType == PROJECTILE_DIRECT && player->weapon->weaponID == WEAPON_FLAME_THROWER)
	{
		if(gameVar.sv_ftExpirationTimer > 0)
		{
			float mult = (1.0f-player->secondsFired/gameVar.sv_ftExpirationTimer) * gameVar.sv_ftMaxRange;
			if (mult < gameVar.sv_ftMinRange)
				mult = gameVar.sv_ftMinRange;
			p2 = p2 * mult;//nuvem's awesome idea, ft range decreases the longer it's fired
			if(gameVar.sv_explodingFT && player->secondsFired/gameVar.sv_ftExpirationTimer > 1)
			{
				scene->server->nukePlayer(playerID);
			}
		}
		else
			p2 = p2 * gameVar.sv_ftMaxRange;
	}
	else
		p2 = p2 * 128;

	p2 = rotateAboutAxis(p2, rand(-imp, imp), CVector3f(0,0,1));
	p2 = rotateAboutAxis(p2, rand(0.0f, 360.0f), dir);
	p2[2] *= .5f;
	p2 += p1;
#endif

	CVector3f normal;

	   if (player->weapon->weaponID == WEAPON_SHOTGUN)
	   {
		   //--- Clamp shot
		   CVector3f dir = p2 - p1;
		   normalize(dir);
		   
         float clampShot;
		 float variation = 0.01f;
         if(gameVar.sv_serverType == SERVER_TYPE_PRO) 
		 {	//clampShot = gameVar.sv_shottyRange;
			 CVector3f sinThetaVector = cross(dir,oldP2);
			 float sinTheta = sinThetaVector.length();
			 clampShot = gameVar.sv_shottyDropRadius/sinTheta;
		 }
		 else 
		 {
	 		 switch(ident)
	 		 {
	 		 case 1:
	 			 clampShot = gameVar.sv_shottyRange*(0.333f+rand(-variation, variation));
				 break;
			 case 2:
				 clampShot = gameVar.sv_shottyRange*(0.667f+rand(-variation, variation));
				 break;
			 case 3:
				 clampShot = gameVar.sv_shottyRange;
				 break;
			 case 4:
				 clampShot = gameVar.sv_shottyRange*(0.667f+rand(-variation, variation));
				 break;
			 case 5:
				 clampShot = gameVar.sv_shottyRange*(0.333f+rand(-variation, variation));
				 break;
			 };
		 }
         
         p2 = p1 + dir * clampShot;
	   }


	bool isCollision = false;

	if (map->rayTest(player->currentCF.position, p1, normal))
	{
		p1 += normal * .01f;
	}

	// On test s'il y a une collision, sinon, f**k it on envoit pas ça
	if (map->rayTest(p1, p2, normal))
	{
		isCollision = true;
	}

	if (player->weapon->weaponID == WEAPON_PHOTON_RIFLE || player->weapon->weaponID == WEAPON_FLAME_THROWER)
	{
		if (player->weapon->weaponID == WEAPON_PHOTON_RIFLE)
		{
			player->p1 = p1;
			player->p2 = p2;
			player->incShot = 30;
		}
		CVector3f p3 = p2;
		// On test premièrement si on touche un autre joueur!
		Player * hitPlayer = 0;
		for (int i=0;i<MAX_PLAYER;i++)
		{
			if (players[i])
			{
				if (i != player->playerID)
				{
#ifdef _PRO_
               if (players[i]->status == PLAYER_STATUS_ALIVE && (players[i]->teamID != player->teamID || gameType == GAME_TYPE_DM || gameType == GAME_TYPE_SND || gameVar.sv_friendlyFire || gameVar.sv_reflectedDamage))
#else
               if (players[i]->status == PLAYER_STATUS_ALIVE && (players[i]->teamID != player->teamID || gameType == GAME_TYPE_DM || gameVar.sv_friendlyFire))
#endif					
					{
						// Ray to sphere test
						if (segmentToSphere(p1, p3, players[i]->currentCF.position, (player->weapon->weaponID == WEAPON_FLAME_THROWER)?.50f:.25f))
						{
							isCollision = true;
							hitPlayer = players[i];
							normal = p3 - p1;
							p3 = p2; // Full length
							normalize(normal);

							// On décrémente sa vie
							hitPlayer->hitSV(gameVar.weapons[player->weapon->weaponID], player, gameVar.weapons[player->weapon->weaponID]->damage);
						}
					}
				}
			}
		}

		// On envoit le résultat à TOUT les joueurs y compris celui qui l'a tiré
		net_svcl_player_shoot playerShootSV;
		playerShootSV.hitPlayerID = -1;
		playerShootSV.playerID = player->playerID;
		playerShootSV.nuzzleID = nuzzleID;
		playerShootSV.p1[0] = (short)(p1[0] * 100);
		playerShootSV.p1[1] = (short)(p1[1] * 100);
		playerShootSV.p1[2] = (short)(p1[2] * 100);
		playerShootSV.p2[0] = (short)(p2[0] * 100);
		playerShootSV.p2[1] = (short)(p2[1] * 100);
		playerShootSV.p2[2] = (short)(p2[2] * 100);
		playerShootSV.normal[0] = (char)(normal[0] * 120);
		playerShootSV.normal[1] = (char)(normal[1] * 120);
		playerShootSV.normal[2] = (char)(normal[2] * 120);
		playerShootSV.weaponID = player->weapon->weaponID;
		bb_serverSend((char*)&playerShootSV,sizeof(net_svcl_player_shoot),NET_SVCL_PLAYER_SHOOT,0);
	}
	else
	{
		// On test premièrement si on touche un autre joueur!
		Player * hitPlayer = 0;
		for (int i=0;i<MAX_PLAYER;i++)
		{
			if (players[i])
			{
				if (i != player->playerID)
				{
					if (players[i]->status == PLAYER_STATUS_ALIVE)
					{
						// Ray to sphere test
						if (segmentToSphere(p1, p2, players[i]->currentCF.position, .25f))
						{
							isCollision = true;
							hitPlayer = players[i];
							normal = p2 - p1;
							normalize(normal);
						}
					}
				}
			}
		}

		// On envoit le résultat à TOUT les joueurs y compris celui qui l'a tiré
		net_svcl_player_shoot playerShootSV;
		if (hitPlayer)
		{
			playerShootSV.hitPlayerID = hitPlayer->playerID;
			playerShootSV.weaponID = player->weapon->weaponID;

			// On décrémente sa vie
			hitPlayer->hitSV(gameVar.weapons[playerShootSV.weaponID], players[player->playerID]);
		}
		else
		{
			playerShootSV.hitPlayerID = -1;
		}
		playerShootSV.playerID = player->playerID;
		playerShootSV.nuzzleID = nuzzleID;
		playerShootSV.p1[0] = (short)(p1[0] * 100);
		playerShootSV.p1[1] = (short)(p1[1] * 100);
		playerShootSV.p1[2] = (short)(p1[2] * 100);
		playerShootSV.p2[0] = (short)(p2[0] * 100);
		playerShootSV.p2[1] = (short)(p2[1] * 100);
		playerShootSV.p2[2] = (short)(p2[2] * 100);
		playerShootSV.normal[0] = (char)(normal[0] * 120);
		playerShootSV.normal[1] = (char)(normal[1] * 120);
		playerShootSV.normal[2] = (char)(normal[2] * 120);
		playerShootSV.weaponID = player->weapon->weaponID;
		bb_serverSend((char*)&playerShootSV,sizeof(net_svcl_player_shoot),NET_SVCL_PLAYER_SHOOT,0);
	}
}