rendered paste body// MENU.H VAR_CAM_PITCH,// MENU.C seth.vars[VAR_CAM_PITCH] = (ethVars_t) { "Spycam Angle", 75.0f, "campitch", CAT_SPYCAM, qfalse, { { "90", 90.0f }, { "85", 85.0f }, { "80", 80.0f }, { "75", 75.0f }, { "70", 70.0f }, { "60", 60.0f }, { "50", 50.0f }, { "45", 45.0f } } };// FINETUNING USE for example /eth_set campitch 55.4// CORRECT CAMERA PITCH EXAMPLE FOR MORTARCAM// (spycam.c)void drawMortarCam() { // Set mortar trajectory from current view vec3_t angles, forward; VectorCopy(eth.cg_refdef.viewaxis[ROLL], forward); // TODO: seems not need VectorCopy(eth.cg_snap->ps.viewangles, angles); angles[PITCH] -= 60.f; AngleVectors(angles, forward, NULL, NULL); forward[0] *= 3000 * 1.1f; forward[1] *= 3000 * 1.1f; forward[2] *= 1500 * 1.1f; trajectory_t mortarTrajectory; mortarTrajectory.trType = TR_GRAVITY; mortarTrajectory.trTime = eth.cg_time; VectorCopy(eth.cg_refdef.vieworg, mortarTrajectory.trBase); // TODO: Not precise need some muzzle VectorCopy(forward, mortarTrajectory.trDelta); // Calculate mortar impact int timeOffset = 0; trace_t mortarTrace; vec3_t mortarImpact; VectorCopy(mortarTrajectory.trBase, mortarImpact); #define TIME_STEP 20 while (timeOffset < 10000) { vec3_t nextPos; timeOffset += TIME_STEP; eth.BG_EvaluateTrajectory(&mortarTrajectory, eth.cg_time + timeOffset, nextPos, qfalse, 0); eth.CG_Trace(&mortarTrace, mortarImpact, 0, 0, nextPos, eth.cg_snap->ps.clientNum, MASK_MISSILESHOT); if ((mortarTrace.fraction != 1) // Check for don't hit sky && !((mortarTrace.surfaceFlags & SURF_NODRAW) || (mortarTrace.surfaceFlags & SURF_NOIMPACT)) && (mortarTrace.contents != 0)) { break; } VectorCopy(nextPos, mortarImpact); } // kobject: add some math to allow for cam pitch angle vec3_t dpos; //x,y vector from mortar impact to us vec3_t campos; //position of camera viewing on mortarimpact vec3_t zaxis; float angle = seth.value[VAR_CAM_PITCH]; // pitch angle, make menu option :P zaxis[0] = 0.0; zaxis[1] = 0.0; zaxis[2] = 1.0; dpos[0] = eth.cg_refdef.vieworg[0]-mortarImpact[0]; dpos[1] = eth.cg_refdef.vieworg[1]-mortarImpact[1]; dpos[2] = 0.0f; VectorNormalize2( dpos, dpos ); VectorCopy( mortarImpact, campos ); VectorMA( campos, seth.value[VAR_MORTARCAM_H]*sinf(angle*M_PI/180.0), zaxis, campos ); VectorMA( campos, seth.value[VAR_MORTARCAM_H]*cosf(angle*M_PI/180.0), dpos, campos ); // Set the view refdef_t camRefDef; memcpy(&camRefDef, ð.cg_refdef, sizeof(refdef_t)); // fov camRefDef.fov_x = 90; camRefDef.fov_y = 90; // origin VectorCopy(campos, camRefDef.vieworg); // angle vec3_t camAngle; VectorCopy(eth.cg_refdefViewAngles, camAngle); camAngle[PITCH] = angle; // Look down AnglesToAxis(camAngle, camRefDef.viewaxis); //initialize window if(!mortarwin.posX) { mortarwin.posX = 10; mortarwin.posY = 10; mortarwin.windowW = 320; mortarwin.windowH = 320; } getWindowStatus(&mortarwin); //clear it anyway memset(&colorCam,0,sizeof(vec4_t)); if (mortarwin.isMouseOn) { colorCam[3]=5.0f; if(mortarwin.isSticked) { int i=0; for (; i < 3 ; i++) colorCam[i] += 0.5f; } } // Draw the mortarcam drawSpyCam(mortarwin.posX, mortarwin.posY, mortarwin.windowW, mortarwin.windowH, &camRefDef, eth.enemyMortarShader, eth.friendMortarShader, qtrue); // Draw impact time char str[128]; sprintf(str, "^0[ ^3Impact in:^2 %.1f ^3seconds ^0]", (float)timeOffset / 1000.0f); drawText(mortarwin.posX + (mortarwin.windowW - sizeTextWidth(0.19f, str, ð.fontVariable)) / 2, mortarwin.posY + mortarwin.windowH - 15, 0.19f, str, colorWhite, qfalse, qtrue, ð.fontVariable);}