//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: A stationary gun that players can man // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "tf_obj_manned_plasmagun_shared.h" #include "tf_movedata.h" ConVar mannedgun_usethirdperson( "mannedgun_usethirdperson", "1", FCVAR_REPLICATED, "Use third person view while in manned guns built on vehicles." ); #define MANNED_PLASMAGUN_AIMING_CONE_ANGLE 45.0f // total angle of aiming #define MANNED_PLASMAGUN_YAW_SPEED 1000.0f #define MANNED_PLASMAGUN_MAX_PITCH 50.0f #define MANNED_PLASMAGUN_BARREL_MAX_PITCH 30.0f float CObjectMannedPlasmagunMovement::GetMaxYaw() const { return MANNED_PLASMAGUN_AIMING_CONE_ANGLE; } float CObjectMannedPlasmagunMovement::GetMinYaw() const { return -MANNED_PLASMAGUN_AIMING_CONE_ANGLE; } float CObjectMannedPlasmagunMovement::GetMaxPitch() const { return MANNED_PLASMAGUN_MAX_PITCH; } void CObjectMannedPlasmagunMovement::ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMove ) { CTFMoveData *pMoveData = (CTFMoveData*)pMove; Assert( sizeof(MannedPlasmagunData_t) <= pMoveData->VehicleDataMaxSize() ); MannedPlasmagunData_t *pVehicleData = (MannedPlasmagunData_t*)pMoveData->VehicleData(); bool bSimple = (pVehicleData->m_nMoveStyle == MOVEMENT_STYLE_SIMPLE); CBaseTFVehicle *pVehicle = pVehicleData->m_pVehicle; // Flush caches since bone controllers might be wrong since they are not in the cache yet pVehicle->InvalidateBoneCache(); // Get the view direction *in world coordinates* Vector vPlayerEye = pPlayer->EyePosition(); QAngle angEyeAngles = pPlayer->LocalEyeAngles(); Vector vPlayerForward; AngleVectors( angEyeAngles, &vPlayerForward, NULL, NULL ); // Now figure out the pitch. This is done by casting a ray to see where the player's aiming reticle is pointing. // Then we do some trig to find out what angle the turret should point so it can see the target. // NOTE: this is done in the tank's local space so it works when the tank is banked. VMatrix mGunToWorld = SetupMatrixTranslation(pVehicle->GetAbsOrigin()) * SetupMatrixAngles(pVehicle->GetAbsAngles()); VMatrix mWorldToGun = mGunToWorld.InverseTR(); // First trace only on the world.. Vector start = vPlayerEye; Vector end = start + vPlayerForward * 5000.0f; Vector vTarget; if ( bSimple ) { vTarget = end; } else { trace_t trace; UTIL_TraceLine(start, end, MASK_SOLID_BRUSHONLY, pVehicle, COLLISION_GROUP_NONE, &trace); vTarget = trace.endpos; if(trace.fraction == 1) { // It didn't hit the world, so trace on ents. UTIL_TraceLine(start, end, MASK_PLAYERSOLID|MASK_NPCSOLID, pVehicle, COLLISION_GROUP_NONE, &trace); vTarget = trace.endpos; if(trace.fraction == 1) { // Didn't hit any ents.. just assume it's way out in front of the player's view. vTarget = end; } } } // Transform the world position into gun space. vTarget = mWorldToGun * vTarget; // Compute the position of the barrel pivot point as measured in the coordinate system of the gun Vector vTurretBase; QAngle vTurretBaseAngles; pVehicle->GetAttachment(pVehicleData->m_nBarrelPivotAttachment, vTurretBase, vTurretBaseAngles); vTurretBase = mWorldToGun * vTurretBase; // Make everything be relative to the pivot... vTarget -= vTurretBase; // Now we've got the target vector in local space. Now just figure out what // the gun angles need to be to hit the target. QAngle vWantedAngles; VectorAngles( vTarget, vWantedAngles ); pVehicleData->m_flGunPitch = vWantedAngles[PITCH]; pVehicleData->m_flGunYaw = vWantedAngles[YAW]; // Place the player at the feet of the vehicle Vector vStandAngles; pVehicle->GetAttachmentLocal(pVehicleData->m_nStandAttachment, pMove->m_vecAbsOrigin, pMove->m_vecAngles); }