//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); }
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()); } } }
// // 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); }
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); } }
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); }
// // 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); } }
// // 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); } } }