예제 #1
0
//deltaX and deltaY are in degrees
static void turn(double *eyeVec, double *atVec, double *upVec, double deltaX, double deltaY) {
  //The idea is to have the camera swivel left when you move the mouse left, and swivel up and down when you move the mouse up and down, without gimbol locking.
  //We accomplish this by having at-eye and up be perpendicular to each other, and keep track of the up orientation outside of this function.
	double upDownRotate[16];
	double leftRightRotate[16];
	double toTransform[16];

	double sideAxis[4] = {0,0,0,0};

	//get sideAxis from up and at (all three should be perpendicular)
	mcross(
		upVec[0],upVec[1],upVec[2],
		atVec[0]-eyeVec[0],atVec[1]-eyeVec[1],atVec[2]-eyeVec[2],
		&sideAxis[0],&sideAxis[1],&sideAxis[2]);
  
	rotateAboutAxis(upDownRotate, deltaY, sideAxis);
    
	setMatTranslation(toTransform, eyeVec[0],eyeVec[1],eyeVec[2]);
	multMatMat(toTransform, upDownRotate, toTransform);
	addMatTranslation(toTransform, -eyeVec[0],-eyeVec[1],-eyeVec[2]);
	multMatVec3(toTransform, atVec, atVec, 1);

	multMatVec3(upDownRotate, upVec,upVec, 0);

	////printf("ud: (%.1lf,%.1lf,%.1lf), ca: (%.1lf,%.1lf,%.1lf) cu: (%.1lf,%.1lf,%.1lf)\n", globalUpDownAxis[0], globalUpDownAxis[1], globalUpDownAxis[2], gCameraAt[0], gCameraAt[1], gCameraAt[2], gCameraUp[0], gCameraUp[1], gCameraUp[2]);

	rotateAboutAxis(leftRightRotate, deltaX, upVec);

	setMatTranslation(toTransform, eyeVec[0],eyeVec[1],eyeVec[2]);
	multMatMat(toTransform, leftRightRotate, toTransform);
	addMatTranslation(toTransform, -eyeVec[0],-eyeVec[1],-eyeVec[2]);
	multMatVec3(toTransform, atVec, atVec, 1);
}
예제 #2
0
파일: Needle.cpp 프로젝트: rll/surgical
void Needle::setTransformFromEndEffectorBoxConstrained(const Vector3d& new_ee_pos, const Matrix3d& new_ee_rot, Box* box)
{
	Vector3d old_ee_pos;
	Matrix3d old_ee_rot;
	getEndEffectorTransform(old_ee_pos, old_ee_rot);

	Vector3d old_proj = (old_ee_pos - position);
	old_proj.normalize();
	Vector3d proj = (new_ee_pos-position).dot(rotation.col(0))*rotation.col(0) + (new_ee_pos-position).dot(rotation.col(2))*rotation.col(2);
	proj.normalize();

	glColor3f(0.8,0.8,0);
	drawArrow(position, 20*proj);
	glColor3f(0.8,0,0);
	drawArrow(position, 20*old_proj);

	Vector3d normal = proj.cross(old_proj);
	normal.normalize();

	double angle = angle_between(proj, old_proj)*180.0/M_PI;
	if (angle > 90.0) {
		angle = 0.0;
		//TODO return;
	} else {
		double sign = ((normal - rotation.col(1)).squaredNorm() < 1e-5) ? -1 : 1;
		angle = sign*min(angle_between(proj, old_proj)*180.0/M_PI, 5.0);
	}

	if (!isnan(angle) && abs(angle)>1e-5 && angle>0.0) { //TODO for now, only allows forward movement of needle through box
		rotateAboutAxis(angle);
		if(isThreadAttached()) {
			thread->updateConstrainedTransform(constraint_ind, getEndPosition(), getEndRotation());
		}
	}
	
	if (isThreadAttached()) {
		Vector3d direction;
		if (!box->isThreadAttached() && (sphereBoxDistance(getEndPosition(), getThicknessRadius(), box->getPosition(), box->getHalfLength(), direction) < 0)) {
		  cout << "thread gets into the box" << endl;
		  //box->attach(getThread());
			box->attachThreadIn(getThread(), getEndPosition(), getEndRotation());
		}
		if (box->isThreadAttached() && !boxCollision(box->getPosition(), box->getHalfLength())) {
		  cout << "thread gets out of the box" << endl;
		  box->attachThreadOut(getThread(), getEndPosition(), getEndRotation());
		}
	}
}
예제 #3
0
//
// Update
//
void Game::update(float delay)
{
  int i;
#ifndef CONSOLE
	dotAnim += delay * 720;
	while (dotAnim >= 360) dotAnim -= 360;
#endif
	if (voting.votingInProgress)
	{
		if (voting.update(delay))
		{
			if (isServerGame)
			{
				//--- Voting complete, check the result
				//    In order to the vote to pass, more than
				//    50% of ALL the players should have voted YES.
				/*voting.nbActivePlayers = 0;
				for (int i=0;i<MAX_PLAYER;++i)
				{
					if ( (players[i]) && (players[i]->teamID != PLAYER_TEAM_AUTO_ASSIGN) &&
						(players[i]->teamID != PLAYER_TEAM_AUTO_ASSIGN) )
						++voting.nbActivePlayers;
				}*/

				net_svcl_vote_result voteResult;
				voteResult.passed = (voting.votingResults[0] > (int)voting.activePlayersID.size() / 2);
				bb_serverSend((char*)(&voteResult), sizeof(net_svcl_vote_result), NET_SVCL_VOTE_RESULT);
				if (voteResult.passed)
				{
					//--- Vote passed!!!
					console->sendCommand(voting.votingWhat);
				}
				else
				{
					//--- Vote failed...
				}
			}
		}
	}

	if (roundState == GAME_PLAYING)
	{
		// On update les players
		for (int i=0;i<MAX_PLAYER;++i) 
		{
			if (players[i])
			{
				players[i]->update(delay);

				if (players[i]->incShot > 0)
				{
					players[i]->incShot--;
					if (players[i]->incShot%3 == 0)
					{
						// On test premièrement si on touche un autre joueur!
						Player * hitPlayer = 0;
						CVector3f p3 = players[i]->p2;
						for (int j=0;j<MAX_PLAYER;j++)
						{
							if (players[j])
							{
								if (j != i)
								{
#ifdef _PRO_
									if (players[j]->status == PLAYER_STATUS_ALIVE && (players[j]->teamID != players[i]->teamID || gameType == GAME_TYPE_DM || gameType == GAME_TYPE_SND || gameVar.sv_friendlyFire || gameVar.sv_reflectedDamage))
#else
									if (players[j]->status == PLAYER_STATUS_ALIVE && (players[j]->teamID != players[i]->teamID || gameType == GAME_TYPE_DM || gameVar.sv_friendlyFire))
#endif
									{
										// Ray to sphere test
										if (segmentToSphere(players[i]->p1, p3, players[j]->currentCF.position, .35f))
										{
											hitPlayer = players[j];
											p3 = players[i]->p2; // Full length

											// On décrémente sa vie
											hitPlayer->hitSV(gameVar.weapons[WEAPON_PHOTON_RIFLE], players[i], gameVar.weapons[WEAPON_PHOTON_RIFLE]->damage / 2.0f);
										}
									}
								}
							}
						}
					}
				}

				//--- Update les guns
				if (players[i]->weapon)
				{
					if (players[i]->weapon->weaponID == WEAPON_SMG)
					{
						if (!gameVar.sv_enableSMG)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_SHOTGUN)
					{
						if (!gameVar.sv_enableShotgun)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_SNIPER)
					{
						if (!gameVar.sv_enableSniper/* || map->size[0] * map->size[1] <= 512*/)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_DUAL_MACHINE_GUN)
					{
						if (!gameVar.sv_enableDualMachineGun)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_CHAIN_GUN)
					{
						if (!gameVar.sv_enableChainGun)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_BAZOOKA)
					{
						if (!gameVar.sv_enableBazooka)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_PHOTON_RIFLE)
					{
						if (!gameVar.sv_enablePhotonRifle)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
					if (players[i]->weapon->weaponID == WEAPON_FLAME_THROWER)
					{
						if (!gameVar.sv_enableFlameThrower)
						{
							players[i]->switchWeapon(SelectToAvailableWeapon(), true);
						}
					}
				}

				//--- Update les melee
				if (players[i]->meleeWeapon)
				{
					if (!gameVar.sv_enableSecondary)
					{
						players[i]->switchMeleeWeapon(SelectToAvailableMeleeWeapon(), true);
					}
					else
					{
						if (players[i]->meleeWeapon->weaponID == WEAPON_KNIVES)
						{
							if (!gameVar.sv_enableKnives)
							{
								players[i]->switchMeleeWeapon(SelectToAvailableMeleeWeapon(), true);
							}
						}
						if (players[i]->meleeWeapon->weaponID == WEAPON_NUCLEAR)
						{
							if (!gameVar.sv_enableNuclear)
							{
								players[i]->switchMeleeWeapon(SelectToAvailableMeleeWeapon(), true);
							}
						}
						if (players[i]->meleeWeapon->weaponID == WEAPON_SHIELD)
						{
							if (!gameVar.sv_enableShield)
							{
								players[i]->switchMeleeWeapon(SelectToAvailableMeleeWeapon(), true);
							}
						}
#ifdef _PRO_
						if (players[i]->meleeWeapon->weaponID == WEAPON_MINIBOT)
						{
							if (!gameVar.sv_enableMinibot)
							{
								players[i]->switchMeleeWeapon(SelectToAvailableMeleeWeapon(), true);
							}
						}
#endif
					}
				}
			}
		}
	}

#ifdef _PRO_
	//--- Perform bot collisions with walls
	if (isServerGame)
	{
		for (int i=0;i<MAX_PLAYER;++i)
		{
			if (players[i])
			{
				if (players[i]->status == PLAYER_STATUS_ALIVE)
				{
					if (players[i]->minibot)
					{
						if (map) map->performCollision(players[i]->minibot->lastCF, players[i]->minibot->currentCF, .15f);
						map->collisionClip(players[i]->minibot->currentCF, .15f);
					}
				}
			}
		}
	}
#endif

	// Si on tiens tab, on montre les stats
#ifndef CONSOLE
	if (!console->isActive() && dkiGetState(gameVar.k_showScore) || roundState != GAME_PLAYING)
	{
		showStats = true;
	}
	else
	{
		showStats = false;
	}

	for (i=0;i<(int)nikeFlashes.size();++i)
	{
		nikeFlashes[i]->update(delay);
		if (nikeFlashes[i]->life <= 0)	 
		{
			delete nikeFlashes[i];
			nikeFlashes.erase(nikeFlashes.begin() + i);
			--i;
		}
	}

	if (thisPlayer && roundState == GAME_PLAYING)
	{
		if (thisPlayer->teamID == PLAYER_TEAM_SPECTATOR && !console->isActive() && !writting && !showMenu && !(menuManager.root && menuManager.root->visible))
		{
			// On est spectateur, alors on peut se déplacer comme on veut dans la map
			// Pour l'instant les flèches (a,s,w,d, pomal temp)
			if (dkiGetState(gameVar.k_moveRight))
			{
				map->camLookAt[0] += 10 * delay;
			}
			if (dkiGetState(gameVar.k_moveLeft))
			{
				map->camLookAt[0] -= 10 * delay;
			}
			if (dkiGetState(gameVar.k_moveUp))
			{
				map->camLookAt[1] += 10 * delay;
			}
			if (dkiGetState(gameVar.k_moveDown))
			{
				map->camLookAt[1] -= 10 * delay;
			}
		}

		// On performe les collisions sur notre joueur
		if (thisPlayer->status == PLAYER_STATUS_ALIVE) 
		{
			for (int i=0;i<MAX_PLAYER;++i)
			{
				if (players[i] && players[i] != thisPlayer)
				{
					if (players[i]->status == PLAYER_STATUS_ALIVE && players[i]->timeAlive > 3.0f && thisPlayer->timeAlive > 3.0f) // player msut have been on the field for more than 3 second before we check collisions with him
					{
						float disSq = distanceSquared(thisPlayer->currentCF.position, players[i]->currentCF.position);
						if (disSq <= .5f*.5f)
						{
							CVector3f dis = players[i]->currentCF.position - thisPlayer->currentCF.position;
							normalize(dis);
							thisPlayer->currentCF.position = players[i]->currentCF.position - dis * .51f;
							thisPlayer->currentCF.vel = -thisPlayer->currentCF.vel * BOUNCE_FACTOR;
							if (map) map->performCollision(thisPlayer->lastCF, thisPlayer->currentCF, .25f);
							map->collisionClip(thisPlayer->currentCF, .25f);
							thisPlayer->lastCF.position = thisPlayer->currentCF.position;
						}
					}
				}
			}

			if (map) map->performCollision(thisPlayer->lastCF, thisPlayer->currentCF, .25f);

			// Performing a final clip cibole de caliss
			map->collisionClip(thisPlayer->currentCF, .25f);

			//--- Est-ce qu'on est stuck dans un wall??? Oui? on respawn request
			int x = (int)thisPlayer->currentCF.position[0];
			int y = (int)thisPlayer->currentCF.position[1];
			if ((!map->dko_map && !map->cells[(y)*map->size[0]+(x)].passable) ||
				(map->dko_map && 
				(x < 0 || x > map->size[0] || y < 0 || y > map->size[1])))
			{
				// Respawn request!
				if (!thisPlayer->spawnRequested)
				{
					// Ici on le call juste une fois, isshh sinon ça sera pas trop bon...
					// On request to spawn
					thisPlayer->spawnRequested = true;
					net_clsv_spawn_request spawnRequest;
					spawnRequest.playerID = thisPlayer->playerID;
					spawnRequest.weaponID = thisPlayer->nextSpawnWeapon;
					spawnRequest.meleeID = thisPlayer->nextMeleeWeapon;
					memcpy(spawnRequest.skin, thisPlayer->skin.s, (thisPlayer->skin.len() <= 6)?thisPlayer->skin.len()+1:7);
					spawnRequest.blueDecal[0] = (unsigned char)(thisPlayer->blueDecal[0] * 255.0f);
					spawnRequest.blueDecal[1] = (unsigned char)(thisPlayer->blueDecal[1] * 255.0f);
					spawnRequest.blueDecal[2] = (unsigned char)(thisPlayer->blueDecal[2] * 255.0f);
					spawnRequest.greenDecal[0] = (unsigned char)(thisPlayer->greenDecal[0] * 255.0f);
					spawnRequest.greenDecal[1] = (unsigned char)(thisPlayer->greenDecal[1] * 255.0f);
					spawnRequest.greenDecal[2] = (unsigned char)(thisPlayer->greenDecal[2] * 255.0f);
					spawnRequest.redDecal[0] = (unsigned char)(thisPlayer->redDecal[0] * 255.0f);
					spawnRequest.redDecal[1] = (unsigned char)(thisPlayer->redDecal[1] * 255.0f);
					spawnRequest.redDecal[2] = (unsigned char)(thisPlayer->redDecal[2] * 255.0f);
					bb_clientSend(scene->client->uniqueClientID, (char*)&spawnRequest, sizeof(net_clsv_spawn_request), NET_CLSV_SPAWN_REQUEST);
				}
			}
		}
	}

	// On update la map
	if (map && thisPlayer) 
	{
		map->update(delay, thisPlayer);

		//--- Est-ce qu'il pleut?
		if (map->weather == WEATHER_RAIN)
		{
			for (int i=0;i<5;++i)
			{
				//--- Spawn da rain!
				int idrip = getNextDrip();
				drips[idrip].life = 1;
				drips[idrip].position = rand(map->camPos + CVector3f(-5,-5,0), map->camPos + CVector3f(5,5,0));
				drips[idrip].position[2] = 0;
				drips[idrip].size = .15f;
				drips[idrip].fadeSpeed = 2;
			}

			//--- Spawn des drip sous les players
			for (int i=0;i<MAX_PLAYER;++i)
			{
				if (players[i])
				{
					if (players[i]->status == PLAYER_STATUS_ALIVE)
					{
						if (map->cells[(int)(players[i]->currentCF.position[1] - .5f) * map->size[0] + (int)(players[i]->currentCF.position[0] - .5f)].splater[0] > .5f)
						{
							if (players[i]->currentCF.vel.length() >= 2.25f)
							{
								//--- Spawn da rain!
								int idrip = getNextDrip();
								drips[idrip].life = .5f;
								drips[idrip].position = players[i]->currentCF.position;
								drips[idrip].position[2] = 0;
								drips[idrip].size = .3f;
								drips[idrip].fadeSpeed = 1;
							}
						}
					}
				}
			}
		}

		//--- Si on roule dans la lave, on spawn de la fumé :D
		if (map->theme == THEME_LAVA)
		{
			//--- Spawn des drip sous les players
			for (int i=0;i<MAX_PLAYER;++i)
			{
				if (players[i])
				{
					if (players[i]->status == PLAYER_STATUS_ALIVE && rand()%50 == 5)
					{
						if (map->cells[(int)(players[i]->currentCF.position[1] - .5f) * map->size[0] + (int)(players[i]->currentCF.position[0] - .5f)].splater[0] > .5f)
						{
							//--- Spawn da smoke psssiiii
							for (int j=0;j<4;++j)
							{
								dkpCreateParticle(	players[i]->currentCF.position.s,//float *position,
													CVector3f(0,0,(float)j* .25f).s,//float *vel,
													CVector4f(.7f,.7f,.7f,1).s,//float *startColor,
													CVector4f(.7f,.7f,.7f,0).s,//float *endColor,
													.25f,//float startSize,
													.5f,//float endSize,
													2,//float duration,
													0,//float gravityInfluence,
													0,//float airResistanceInfluence,
													30,//float rotationSpeed,
													gameVar.tex_smoke1,//unsigned int texture,
													DKP_SRC_ALPHA,//unsigned int srcBlend,
													DKP_ONE_MINUS_SRC_ALPHA,//unsigned int dstBlend,
													0);//int transitionFunc);
							}

							dksPlay3DSound(gameVar.sfx_lavaSteam, -1, 5, players[i]->currentCF.position,125);
						}
					}
				}
			}
		}

		// La view qui shake
		if (viewShake > 0)
		{
			if (viewShake > 2.5f) viewShake = 2.5f;

			CVector3f dir(1,0,0);
			dir = rotateAboutAxis(dir, rand(0.0f, 360.0f), CVector3f(0,0,1));
			dir *= viewShake * .10f;

			map->camPos += dir;
			viewShake -= delay*.75f;
			if (viewShake < 0) viewShake = 0;
		}


		//-- We check for all enable guns
		scene->client->btn_guns[WEAPON_SMG]->enable = gameVar.sv_enableSMG;
		scene->client->btn_guns[WEAPON_SHOTGUN]->enable = gameVar.sv_enableShotgun;
		scene->client->btn_guns[WEAPON_SNIPER]->enable = gameVar.sv_enableSniper;
		scene->client->btn_guns[WEAPON_DUAL_MACHINE_GUN]->enable = gameVar.sv_enableDualMachineGun;
		scene->client->btn_guns[WEAPON_CHAIN_GUN]->enable = gameVar.sv_enableChainGun;
		scene->client->btn_guns[WEAPON_BAZOOKA]->enable = gameVar.sv_enableBazooka;
		scene->client->btn_guns[WEAPON_PHOTON_RIFLE]->enable = gameVar.sv_enablePhotonRifle;
		scene->client->btn_guns[WEAPON_FLAME_THROWER]->enable = gameVar.sv_enableFlameThrower;
		
		if(gameVar.sv_enableSecondary)
		{
			scene->client->btn_meleeguns[WEAPON_KNIVES-WEAPON_KNIVES]->enable = gameVar.sv_enableKnives;
			scene->client->btn_meleeguns[WEAPON_NUCLEAR-WEAPON_KNIVES]->enable = gameVar.sv_enableNuclear;
			scene->client->btn_meleeguns[WEAPON_SHIELD-WEAPON_KNIVES]->enable = gameVar.sv_enableShield;
			scene->client->btn_meleeguns[WEAPON_MINIBOT-WEAPON_KNIVES]->enable = gameVar.sv_enableMinibot;
		}
		else
		{
			scene->client->btn_meleeguns[WEAPON_KNIVES-WEAPON_KNIVES]->enable = false;
			scene->client->btn_meleeguns[WEAPON_NUCLEAR-WEAPON_KNIVES]->enable = false;
			scene->client->btn_meleeguns[WEAPON_SHIELD-WEAPON_KNIVES]->enable = false;
			scene->client->btn_meleeguns[WEAPON_MINIBOT-WEAPON_KNIVES]->enable = false;
		}

	}

	// On update les trails
	for (int i=0;i<(int)trails.size();++i)
	{
		trails[i]->update(delay);
		if (trails[i]->delay >= 1)
		{
			delete trails[i];
			trails.erase(trails.begin()+i);
			i--;
		}
	}

	// On update les floor mark
	for (int i=0;i<MAX_FLOOR_MARK;++i)
	{
		if (floorMarks[i].delay > 0)
		{
			floorMarks[i].update(delay);
		}
		if (drips[i].life > 0)
		{
			drips[i].update(delay);
		}
	}
#endif

	// On update les projectiles
	for (int i=0;i<(int)projectiles.size();++i)
	{
		Projectile * projectile = projectiles[i];
		projectile->update(delay, map);
		projectile->projectileID = (short)i; // On l'update toujours
		if ( projectile->needToBeDeleted )
		{
			if( !projectile->reallyNeedToBeDeleted )
			{
				projectile->reallyNeedToBeDeleted = true;
				continue;
			}
			projectiles.erase(projectiles.begin()+i);
			net_svcl_delete_projectile deleteProjectile;
			deleteProjectile.projectileID = projectile->uniqueID;
			bb_serverSend((char*)&deleteProjectile,sizeof(net_svcl_delete_projectile),NET_SVCL_DELETE_PROJECTILE,0);
			i--;
			delete projectile;
		}

	}

#ifndef CONSOLE

	// On update les projectiles client
	for (int i=0;i<(int)clientProjectiles.size();++i)
	{
		Projectile * projectile = clientProjectiles[i];
		projectile->update(delay, map);
		projectile->projectileID = (short)i; // On l'update toujours
		if (projectile->needToBeDeleted)
		{
			clientProjectiles.erase(projectiles.begin()+i);
			i--;
			delete projectile;
		}
	}

	// On update les douilles
	for (int i=0;i<(int)douilles.size();++i)
	{
		Douille * douille = douilles[i];
		douille->update(delay, map);
		if (douille->delay<=0)
		{
			douilles.erase(douilles.begin()+i);
			i--;
			delete douille;
		}
	}
#endif	

	// Update les particules
//	gameVar.ro_nbParticle = dkpUpdate(delay);
}
예제 #4
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);
	}
}
예제 #5
0
void Game::shootMinibotSV(CMiniBot * minibot, float imp, CVector3f p1, CVector3f p2)
{
	CVector3f normal;

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

	// On test s'il y a une collision
	map->rayTest(p1, p2, normal);

	// 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 != minibot->owner->playerID)
			{
				if (players[i]->status == PLAYER_STATUS_ALIVE)
           //    if (players[i]->status == PLAYER_STATUS_ALIVE && (players[i]->teamID != player->teamID || gameType == GAME_TYPE_DM || gameType == GAME_TYPE_SND || gameVar.sv_friendlyFire))
				{
					// Ray to sphere test
					if (segmentToSphere(p1, p2, players[i]->currentCF.position, .25f))
					{
						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 = WEAPON_MINIBOT_WEAPON;

		// On décrémente sa vie
		hitPlayer->hitSV(gameVar.weapons[WEAPON_MINIBOT], players[minibot->owner->playerID]);
	}
	else
	{
		playerShootSV.hitPlayerID = -1;
	}
	playerShootSV.playerID = minibot->owner->playerID;
	playerShootSV.nuzzleID = 0;
	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 = WEAPON_MINIBOT_WEAPON;
	bb_serverSend((char*)&playerShootSV,sizeof(net_svcl_player_shoot),NET_SVCL_PLAYER_SHOOT,0);
}
예제 #6
0
//
// Quand un client shot, mais que le server le vérifie puis le shoot aux autres joueurs
//
void Game::shootSV(net_clsv_player_shoot & playerShoot)
{
	Player* player = players[playerShoot.playerID];
	if (player == 0)
		return;

	CVector3f p1;/*(playerShoot.p1);*/
	CVector3f p2;/*(playerShoot.p2);*/
	p1[0] = (float)playerShoot.p1[0] / 100.0f;
	p1[1] = (float)playerShoot.p1[1] / 100.0f;
	p1[2] = (float)playerShoot.p1[2] / 100.0f;
	p2[0] = (float)playerShoot.p2[0] / 100.0f;
	p2[1] = (float)playerShoot.p2[1] / 100.0f;
	p2[2] = (float)playerShoot.p2[2] / 100.0f;
	player->weapon->shotFrom = p1;

#ifdef _PRO_
	if (player->weapon->weaponID == WEAPON_SHOTGUN)
	{
		// ves's suggestion
		const float directionAngles[5] = {-10.0f, -5.0f, 0.0f, 5.0f, 10.0f};
		const float deviationAngles[5] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f};//for the moment, these simply identify which shots are which, the actual deviation is fixed in the next call to shootSV
		// adder's suggestion
		//const float directionAngles[7] = {0.0f, 7.0f, -7.0f, 3.5f, -3.5f, 10.5f, -10.5f};
		//const float deviationAngles[7] = {3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f};
		CVector3f newP2;
		for (int i=0;i<player->weapon->nbShot;++i)
		{
			newP2 = rotateAboutAxis(p2, directionAngles[i], CVector3f(0.0f, 0.0f, 1.0f));
			shootSV(playerShoot.playerID, playerShoot.nuzzleID, deviationAngles[i], p1, newP2);
		}
	}
	else if (player->weapon->weaponID == WEAPON_SNIPER)
	{
		for (int i=0;i<player->weapon->nbShot;++i)
			shootSV(playerShoot.playerID, playerShoot.nuzzleID, 0, p1, p2);
	}
	else if (player->weapon->weaponID == WEAPON_CHAIN_GUN)
   {
		player->weapon->currentImp += 3;
		if (player->weapon->currentImp > player->weapon->impressision)
			player->weapon->currentImp = player->weapon->impressision;

      float imp = player->weapon->currentImp;      
      
      if (gameVar.sv_serverType == SERVER_TYPE_PRO)
         {
         if (player->currentCF.vel.length() < 1.15f)
            {
            imp /= 2.70f;
            }
         }


		for (int i=0;i<player->weapon->nbShot;++i)
			shootSV(playerShoot.playerID, playerShoot.nuzzleID, imp, p1, p2);
   }
   else
#endif
	{
		player->weapon->currentImp += 3;
		if (player->weapon->currentImp > player->weapon->impressision)
			player->weapon->currentImp = player->weapon->impressision;
		for (int i=0;i<player->weapon->nbShot;++i)
			shootSV(playerShoot.playerID, playerShoot.nuzzleID, player->weapon->currentImp, p1, p2);
	}
}
예제 #7
0
//
// Pour ajouter une trainer d'une shot
//
void Game::shoot(const CVector3f & position, const CVector3f & direction, float imp, float damage, Player * from, int projectileType)
{
	if (map)
	{
		CVector3f p2 = direction * 128; // Ça c'est le range, 128 c'est assez, grosseur max de map (c f*****g big ça)
		if (projectileType == PROJECTILE_DIRECT && from->weapon->weaponID == WEAPON_FLAME_THROWER)
		{
			p2 = direction * 3;
		}
		p2 = rotateAboutAxis(p2, rand(-imp, imp), CVector3f(0,0,1));
		p2 = rotateAboutAxis(p2, rand(0.0f, 360.0f), direction);
		p2[2] *= .5f;
		p2 += position;

		if (projectileType == PROJECTILE_DIRECT && from->weapon)
		{
			net_clsv_player_shoot playerShoot;
			playerShoot.playerID = from->playerID;
			playerShoot.nuzzleID = (char)from->weapon->firingNuzzle;
			playerShoot.p1[0] = (short)(position[0] * 100);
			playerShoot.p1[1] = (short)(position[1] * 100);
			playerShoot.p1[2] = (short)(position[2] * 100);
#ifdef _PRO_
			playerShoot.p2[0] = (short)(direction[0] * 100);
			playerShoot.p2[1] = (short)(direction[1] * 100);
			playerShoot.p2[2] = (short)(direction[2] * 100);
#else
			playerShoot.p2[0] = (short)(p2[0] * 100);
			playerShoot.p2[1] = (short)(p2[1] * 100);
			playerShoot.p2[2] = (short)(p2[2] * 100);
#endif
			playerShoot.weaponID = from->weapon->weaponID;
			bb_clientSend(scene->client->uniqueClientID, (char*)&playerShoot,sizeof(net_clsv_player_shoot),NET_CLSV_PLAYER_SHOOT);
		}
		else if (projectileType == PROJECTILE_ROCKET && from->weapon)
		{
			// On demande au server de créer une instance d'une rocket
			net_clsv_svcl_player_projectile playerProjectile;
			playerProjectile.playerID = from->playerID;
			playerProjectile.nuzzleID = (char)from->weapon->firingNuzzle;
			playerProjectile.projectileType = (char)projectileType;
			playerProjectile.weaponID = from->weapon->weaponID;
			playerProjectile.position[0] = (short)(position[0] * 100.0f);
			playerProjectile.position[1] = (short)(position[1] * 100.0f);
			playerProjectile.position[2] = (short)(position[2] * 100.0f);
		//	CVector3f dir = from->currentCF.mousePosOnMap - position; // Pas une bonne idée ça, trop facile
		//	normalize(dir);
			playerProjectile.vel[0] = (char)(direction[0] * 10.0f);
			playerProjectile.vel[1] = (char)(direction[1] * 10.0f);
			playerProjectile.vel[2] = (char)(direction[2] * 10.0f);
			bb_clientSend(scene->client->uniqueClientID, (char*)&playerProjectile,sizeof(net_clsv_svcl_player_projectile),NET_CLSV_SVCL_PLAYER_PROJECTILE);

			// duplicate rocket was for hacking test only
			//playerProjectile.vel[1] = (char)(direction[0] * 10.0f);
			//playerProjectile.vel[2] = (char)(direction[1] * 10.0f);
			//playerProjectile.vel[0] = (char)(direction[2] * 10.0f);

			//bb_clientSend(scene->client->uniqueClientID, (char*)&playerProjectile,sizeof(net_clsv_svcl_player_projectile),NET_CLSV_SVCL_PLAYER_PROJECTILE);
		}
		else if (projectileType == PROJECTILE_GRENADE)
		{
		//	for (int i=0;i<20;++i)
		//	{
				// On demande au server de créer une instance d'une grenade
				net_clsv_svcl_player_projectile playerProjectile;
				playerProjectile.playerID = from->playerID;
				playerProjectile.nuzzleID = (char)from->weapon->firingNuzzle;
				playerProjectile.projectileType = (char)projectileType;
				playerProjectile.weaponID = WEAPON_GRENADE;
				playerProjectile.position[0] = (short)(position[0] * 100.0f);
				playerProjectile.position[1] = (short)(position[1] * 100.0f);
				playerProjectile.position[2] = (short)(position[2] * 100.0f);
			//	CVector3f dir = from->currentCF.mousePosOnMap - position; // Pas une bonne idée ça, trop facile
			//	normalize(dir);
				playerProjectile.vel[0] = (char)(direction[0] * 10.0f);
				playerProjectile.vel[1] = (char)(direction[1] * 10.0f);
				playerProjectile.vel[2] = (char)(direction[2] * 10.0f);
				bb_clientSend(scene->client->uniqueClientID, (char*)&playerProjectile,sizeof(net_clsv_svcl_player_projectile),NET_CLSV_SVCL_PLAYER_PROJECTILE);
		//	}
		}
		else if (projectileType == PROJECTILE_COCKTAIL_MOLOTOV)
		{
			// On demande au server de créer une instance d'une grenade
			net_clsv_svcl_player_projectile playerProjectile;
			playerProjectile.playerID = from->playerID;
			playerProjectile.nuzzleID = (char)from->weapon->firingNuzzle;
			playerProjectile.projectileType = (char)projectileType;
			playerProjectile.weaponID = WEAPON_COCKTAIL_MOLOTOV;
			playerProjectile.position[0] = (short)(position[0] * 100.0f);
			playerProjectile.position[1] = (short)(position[1] * 100.0f);
			playerProjectile.position[2] = (short)(position[2] * 100.0f);
		//	CVector3f dir = from->currentCF.mousePosOnMap - position; // Pas une bonne idée ça, trop facile
		//	normalize(dir);
			playerProjectile.vel[0] = (char)(direction[0] * 10.0f);
			playerProjectile.vel[1] = (char)(direction[1] * 10.0f);
			playerProjectile.vel[2] = (char)(direction[2] * 10.0f);
			bb_clientSend(scene->client->uniqueClientID, (char*)&playerProjectile,sizeof(net_clsv_svcl_player_projectile),NET_CLSV_SVCL_PLAYER_PROJECTILE);
		}
	}
}