Esempio n. 1
0
bool IsInViewCone (Vector origin, edict_t *ent)
{
   MakeVectors (ent->v.v_angle);

   if (((origin - (ent->v.origin + ent->v.view_ofs)).Normalize () | g_pGlobals->v_forward) >= cosf (((ent->v.fov > 0 ? ent->v.fov : 90.0f) / 2) * Math::MATH_PI / 180.0f))
      return true;

   return false;
}
Esempio n. 2
0
void NPC::MoveAction(void)
{
	if ((g_waypoint->g_waypointPointFlag[m_currentWaypointIndex] & WAYPOINT_LADDER &&
		GetDistance2D(pev->origin, g_waypoint->g_waypointPointOrigin[m_currentWaypointIndex]) <= 10.0f) ||
		(m_oldNavIndex != -1 && g_waypoint->g_waypointPointFlag[m_oldNavIndex] & WAYPOINT_LADDER &&
			GetDistance2D(pev->origin, g_waypoint->g_waypointPointOrigin[m_oldNavIndex]) <= 10.0f))
		pev->movetype = MOVETYPE_FLY;
	else
		pev->movetype = MOVETYPE_PUSHSTEP;

	float oldSpeed = pev->speed;
	pev->speed = m_moveSpeed;
	if (m_moveSpeed == 0.0f || !IsAlive (GetEntity ()))
	{
		if (!IsOnLadder(GetEntity()) && pev->solid != SOLID_NOT)
			DROP_TO_FLOOR(GetEntity());
		return;
	}

	if (IsOnLadder(GetEntity()) || pev->solid == SOLID_NOT)
	{
		pev->velocity = GetSpeedVector(pev->origin, m_destOrigin, pev->speed);

		if (pev->solid == SOLID_NOT)
			goto lastly;
	}
	else
	{
		Vector vecMove = m_destOrigin - pev->origin;
		Vector vecFwd, vecAng;
		VEC_TO_ANGLES(vecMove, vecAng);
		vecAng = Vector(0.0f, vecAng.y, 0.0f);
		UTIL_MakeVectorsPrivate(vecAng, vecFwd, null, null);

		pev->velocity.x = vecFwd.x * pev->speed;
		pev->velocity.y = vecFwd.y * pev->speed;
	}

	if (m_jumpAction)
	{
		pev->velocity.z = (270.0f * pev->gravity) + 32.0f; // client gravity 1 = 270.0f , and jump+duck + 32.0f
		m_jumpAction = false;
	}

	CheckStuck(oldSpeed);

	lastly:
	float speed = GetDistance2D(pev->velocity);
	if (speed > 10.0f || speed < -10.0f)
		g_npcAS |= ASC_MOVE;

	MakeVectors(pev->angles);
}
Esempio n. 3
0
//
// ObstacleDistance - returns normalized distance to obstacle
//
float CLeech::ObstacleDistance( CBaseEntity *pTarget )
{
	TraceResult		tr;
	Vector			vecTest;

	// use VELOCITY, not angles, not all boids point the direction they are flying
	//Vector vecDir = UTIL_VecToAngles( pev->velocity );
	MakeVectors();

	// check for obstacle ahead
	vecTest = pev->origin + gpGlobals->v_forward * LEECH_CHECK_DIST;
	UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr);

	if ( tr.fStartSolid )
	{
		pev->speed = -LEECH_SWIM_SPEED * 0.5;
//		ALERT( at_console, "Stuck from (%f %f %f) to (%f %f %f)\n", pev->oldorigin.x, pev->oldorigin.y, pev->oldorigin.z, pev->origin.x, pev->origin.y, pev->origin.z );
//		UTIL_SetOrigin( pev, pev->oldorigin );
	}

	if ( tr.flFraction != 1.0 )
	{
		if ( (pTarget == NULL || tr.pHit != pTarget->edict()) )
		{
			return tr.flFraction;
		}
		else
		{
			if ( fabs(m_height - pev->origin.z) > 10 )
				return tr.flFraction;
		}
	}

	if ( m_sideTime < gpGlobals->time )
	{
		// extra wide checks
		vecTest = pev->origin + gpGlobals->v_right * LEECH_SIZEX * 2 + gpGlobals->v_forward * LEECH_CHECK_DIST;
		UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr);
		if (tr.flFraction != 1.0)
			return tr.flFraction;

		vecTest = pev->origin - gpGlobals->v_right * LEECH_SIZEX * 2 + gpGlobals->v_forward * LEECH_CHECK_DIST;
		UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr);
		if (tr.flFraction != 1.0)
			return tr.flFraction;

		// Didn't hit either side, so stop testing for another 0.5 - 1 seconds
		m_sideTime = gpGlobals->time + RANDOM_FLOAT(0.5,1);
	}
	return 1.0;
}
Esempio n. 4
0
bool Bot::IsFriendInLineOfFire (float distance)
{
   // bot can't hurt teammates, if friendly fire is not enabled...
   if (!engine->IsFriendlyFireOn ())
      return false;

   MakeVectors (pev->v_angle);

   TraceResult tr;
   TraceLine (EyePosition (), EyePosition () + pev->v_angle.Normalize () * distance, false, false, GetEntity (), &tr);

   // check if we hit something
   if (!FNullEnt (tr.pHit))
   {
      int playerIndex = ENTINDEX (tr.pHit) - 1;

      // check valid range
      if (playerIndex >= 0 && playerIndex < engine->GetMaxClients () && g_clients[playerIndex].team == GetTeam (GetEntity ()) && (g_clients[playerIndex].flags & CFLAG_ALIVE))
         return true;
   }

   // search the world for players
   for (int i = 0; i < engine->GetMaxClients (); i++)
   {
      if (!(g_clients[i].flags & CFLAG_USED) || !(g_clients[i].flags & CFLAG_ALIVE) || g_clients[i].team != GetTeam (GetEntity ()) || g_clients[i].ent == GetEntity ())
         continue;

      edict_t *ent = g_clients[i].ent;

      float friendDistance = (GetEntityOrigin (ent) - pev->origin).GetLength ();
      float squareDistance = sqrtf (1089.0f + (friendDistance * friendDistance));

      if ((GetShootingConeDeviation (GetEntity (), &GetEntityOrigin (ent))) > 
		  ((friendDistance * friendDistance) / (squareDistance * squareDistance)) && 
		  friendDistance <= distance)
         return true;
   }
   return false;
}
Esempio n. 5
0
bool NPC::AttackAction(edict_t *entity, bool needSetSpeed)
{
	if (FNullEnt(entity) || !IsAlive(entity))
		return false;

	if (!IsOnAttackDistance(entity, m_attackDistance))
		return false;

	if (needSetSpeed)
		m_moveSpeed = 0.0f;

	if ((m_attackTime + m_attackDelayTime) <= gpGlobals->time)
	{
		TraceResult tr;
		UTIL_TraceLine(pev->origin, GetEntityOrigin(entity), ignore_monsters, GetEntity(), &tr);
		if (tr.pHit != entity && tr.flFraction < 1.0f)
			return false;

		g_npcAS |= ASC_ATTACK;
		m_attackTime = gpGlobals->time;
		m_changeActionTime = -1.0f;

		MakeVectors(pev->angles);
		float x = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
		float y = RANDOM_FLOAT(-0.5, 0.5) + RANDOM_FLOAT(-0.5, 0.5);
		Vector vecDir = gpGlobals->v_forward + x * 0.15 * gpGlobals->v_right + y * 0.15 * gpGlobals->v_up;

		TakeDamage(m_enemy, GetEntity(), m_attackDamage, 0, tr.vecEndPos, vecDir);

		if (strcmp(m_npcSound[NS_ATTACK], "null") != 0)
			EMIT_SOUND_DYN(GetEntity(), CHAN_WEAPON, m_npcSound[NS_ATTACK], VOL_NORM, ATTN_NORM, 0, 94);

		return true;
	}

	return false;
}
Esempio n. 6
0
bool Aiming::Aim(double deltaT, Vector3 const camOrigin, double & yPitch, double & zYaw, double & xRoll)
{
	if(deltaT <= 0)
	{
		return false;
	}

	bool camRotationChanged = false;

	m_Deactivating = Active || m_Deactivating && SoftDeactivate;

	double targetYPitch = yPitch;
	double targetZYaw = zYaw;
	double targetXRoll = xRoll;

	if(Active)
	{
		IClientEntity_csgo * ce = g_Entitylist_csgo->GetClientEntity(EntityIndex);
		C_BaseEntity_csgo * be = ce ? ce->GetBaseEntity() : 0;

		if(ce)
		{
			Vector o =  be && O_View == Origin ? be->EyePosition() : ce->GetAbsOrigin();
			QAngle a =  be && A_View == Angles ? be->EyeAngles() : ce->GetAbsAngles();

			double forward[3], right[3], up[3];

			MakeVectors(a.z, a.x, a.y, forward, right, up);

			LastTargetOrigin = Vector3(
				o.x +OffSet.X * forward[0] + OffSet.Y * right[0] +OffSet.Z * up[0],
				o.y +OffSet.X * forward[1] + OffSet.Y * right[1] +OffSet.Z * up[1],
				o.z +OffSet.X * forward[2] + OffSet.Y * right[2] +OffSet.Z * up[2]
			);

		}
	}
	else
	{
		LastTargetOrigin = camOrigin;
	}

	if(Active || m_Deactivating)
	{
		if(Active)
		{
			LookAnglesFromTo(camOrigin, LastTargetOrigin, LastYPitch, LastZYaw, targetYPitch, targetZYaw);
			targetXRoll = U_World == Up ? 0 : targetXRoll;
		}

		if(SnapTo)
		{
			yPitch = targetYPitch;
			zYaw = targetZYaw;
			xRoll = targetXRoll;
			camRotationChanged = true;
			m_Deactivating = false;
		}
		else
		{
			double reaimYPitch = targetYPitch -LastYPitch;
			double reaimZYaw = targetZYaw -LastZYaw;
			double reaimXRoll = targetXRoll -LastXRoll;

			// Force reaim angles to be in [-180°, 180°)

			reaimYPitch = fmod(reaimYPitch + 180.0, 360.0) -180.0;
			reaimZYaw = fmod(reaimZYaw + 180.0, 360.0) -180.0;
			reaimXRoll = fmod(reaimXRoll + 180.0, 360.0) -180.0;

			m_Deactivating = Active || abs(reaimYPitch) > AFX_MATH_EPS || abs(reaimZYaw) > AFX_MATH_EPS || abs(reaimXRoll) > AFX_MATH_EPS;

			// apply re-aiming:

			//Tier0_Msg("+++pitch+++\n");
			CalcSmooth(deltaT, LastYPitch +reaimYPitch, LastYPitch, m_YPitchVelocity);
			yPitch = LastYPitch;

			//Tier0_Msg("+++yaw+++\n");
			CalcSmooth(deltaT, LastZYaw +reaimZYaw, LastZYaw, m_ZYawVelocity);
			zYaw = LastZYaw;

			//Tier0_Msg("+++roll+++\n");
			CalcSmooth(deltaT, LastXRoll +reaimXRoll, LastXRoll, m_XRollVelocity);
			xRoll = LastXRoll;

			camRotationChanged = true;
		}
	}
	else
	{
		m_YPitchVelocity = 0;
		m_ZYawVelocity = 0;
		m_XRollVelocity = 0;
	}

	// Force remembered angels to be in [-180°, 180°)

	LastYPitch = fmod(yPitch +180.0, 360.0) -180.0;
	LastZYaw = fmod(zYaw +180.0, 360.0) -180.0;
	LastXRoll = fmod(xRoll +180.0, 360.0) -180.0;

	return camRotationChanged;
}
Esempio n. 7
0
void Bot::CombatFight (void)
{
   // no enemy? no need to do strafing
   if (FNullEnt (m_enemy))
      return;

   Vector enemyOrigin = m_lookAt;

   if (m_currentWeapon == WEAPON_KNIFE)
      m_destOrigin = m_enemy->v.origin;

   enemyOrigin = (enemyOrigin - EyePosition ()).SkipZ (); // ignore z component (up & down)

   float distance = enemyOrigin.GetLength ();  // how far away is the enemy scum?

   if (m_timeWaypointMove + m_frameInterval < engine->GetTime ())
   {
      if (m_currentWeapon == WEAPON_KNIFE)
         return;

      int approach;

      if ((m_states & STATE_SUSPECTENEMY) && !(m_states & STATE_SEEINGENEMY)) // if suspecting enemy stand still
         approach = 49;
      else if (m_isReloading || m_isVIP) // if reloading or vip back off
         approach = 29;
      else if (m_currentWeapon == WEAPON_KNIFE) // knife?
         approach = 100;
      else
      {
         approach = static_cast <int> (pev->health * m_agressionLevel);

         if (UsesSniper () && (approach > 49))
            approach = 49;
      }

      // only take cover when bomb is not planted and enemy can see the bot or the bot is VIP
      if (approach < 30 && !g_bombPlanted && (::IsInViewCone (pev->origin, m_enemy) || m_isVIP))
      {
         m_moveSpeed = -pev->maxspeed;

         GetCurrentTask ()->taskID = TASK_SEEKCOVER;
         GetCurrentTask ()->canContinue = true;
         GetCurrentTask ()->desire = TASKPRI_FIGHTENEMY + 1.0f;
      }
      else if (approach < 50)
         m_moveSpeed = 0.0f;
      else
         m_moveSpeed = pev->maxspeed;

      if (distance < 96 && m_currentWeapon != WEAPON_KNIFE)
         m_moveSpeed = -pev->maxspeed;

      if (UsesSniper ())
      {
         m_fightStyle = 1;
         m_lastFightStyleCheck = engine->GetTime ();
      }
      else if (UsesRifle () || UsesSubmachineGun ())
      {
         if (m_lastFightStyleCheck + 3.0f < engine->GetTime ())
         {
            int rand = engine->RandomInt (1, 100);

            if (distance < 450)
               m_fightStyle = 0;
            else if (distance < 1024)
            {
               if (rand < (UsesSubmachineGun () ? 50 : 30))
                  m_fightStyle = 0;
               else
                  m_fightStyle = 1;
            }
            else
            {
               if (rand < (UsesSubmachineGun () ? 80 : 93))
                  m_fightStyle = 1;
               else
                  m_fightStyle = 0;
            }
            m_lastFightStyleCheck = engine->GetTime ();
         }
      }
      else
      {
         if (m_lastFightStyleCheck + 3.0f < engine->GetTime ())
         {
            if (engine->RandomInt (0, 100) < 65)
               m_fightStyle = 1;
            else
               m_fightStyle = 0;

            m_lastFightStyleCheck = engine->GetTime ();
         }
      }

      if ((m_skill > 50 && m_fightStyle == 0) || ((pev->button & IN_RELOAD) || m_isReloading) || (UsesPistol () && distance < 500.0f))
      {
         if (m_strafeSetTime < engine->GetTime ())
         {
            // to start strafing, we have to first figure out if the target is on the left side or right side
            MakeVectors (m_enemy->v.v_angle);

            Vector dirToPoint = (pev->origin - m_enemy->v.origin).Normalize2D ();
            Vector rightSide = g_pGlobals->v_right.Normalize2D ();

            if ((dirToPoint | rightSide) < 0)
               m_combatStrafeDir = 1;
            else
               m_combatStrafeDir = 0;

            if (engine->RandomInt (1, 100) < 30)
               m_combatStrafeDir ^= 1;

            m_strafeSetTime = engine->GetTime () + engine->RandomFloat (0.5, 2.5);
         }

         if (m_combatStrafeDir == 0)
         {
            if (!CheckWallOnLeft ())
               m_strafeSpeed = -160.0f;
            else
            {
               m_combatStrafeDir ^= 1;
               m_strafeSetTime = engine->GetTime () + 0.7f;
            }
         }
         else
         {
            if (!CheckWallOnRight ())
               m_strafeSpeed = 160.0f;
            else
            {
               m_combatStrafeDir ^= 1;
               m_strafeSetTime = engine->GetTime () + 1.0f;
            }
         }

         if (m_skill > 80 && (m_jumpTime + 5.0f < engine->GetTime () && IsOnFloor () && engine->RandomInt (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D () > 150.0f))
            pev->button |= IN_JUMP;

         if (m_moveSpeed != 0.0f && distance > 150.0f)
            m_moveSpeed = 0.0f;
      }
      else if (m_fightStyle == 1)
      {
         bool shouldDuck = true; // should duck

         // check the enemy height
         float enemyHalfHeight = ((m_enemy->v.flags & FL_DUCKING) == FL_DUCKING ? 36.0f : 72.0f) / 2;

         // check center/feet
         if (!IsVisible (m_enemy->v.origin, GetEntity ()) && !IsVisible (m_enemy->v.origin + Vector (0, 0, -enemyHalfHeight), GetEntity ()))
            shouldDuck = false;

         int nearestToEnemyPoint = g_waypoint->FindNearest (m_enemy->v.origin);

         if (shouldDuck && GetCurrentTask ()->taskID != TASK_SEEKCOVER && GetCurrentTask ()->taskID != TASK_HUNTENEMY && (m_visibility & VISIBILITY_BODY) && !(m_visibility & VISIBILITY_OTHER) && g_waypoint->IsDuckVisible (m_currentWaypointIndex, nearestToEnemyPoint))
            m_duckTime = engine->GetTime () + m_frameInterval * 3.5f;

         m_moveSpeed = 0.0f;
         m_strafeSpeed = 0.0f;
         m_navTimeset = engine->GetTime ();
      }
   }

   if (m_duckTime > engine->GetTime ())
   {
      m_moveSpeed = 0.0f;
      m_strafeSpeed = 0.0f;
   }

   if (m_moveSpeed != 0.0f)
      m_moveSpeed = GetWalkSpeed ();

   if (m_isReloading)
   {
      m_moveSpeed = -pev->maxspeed;
      m_duckTime = engine->GetTime () - (m_frameInterval * 4.0f);
   }

   if (!IsInWater () && !IsOnLadder () && (m_moveSpeed != 0 || m_strafeSpeed != 0))
   {
      MakeVectors (pev->v_angle);

      if (IsDeadlyDrop (pev->origin + (g_pGlobals->v_forward * m_moveSpeed * 0.2f) + (g_pGlobals->v_right * m_strafeSpeed * 0.2f) + (pev->velocity * m_frameInterval)))
      {
         m_strafeSpeed = -m_strafeSpeed;
         m_moveSpeed = -m_moveSpeed;

         pev->button &= ~IN_JUMP;
      }
   }
}
Esempio n. 8
0
void Hook_VClient_RenderView::OnViewOverride(float &Tx, float &Ty, float &Tz, float &Rx, float &Ry, float &Rz, float &Fov)
{
	float curTime = GetCurTime();

	if(m_CamPath.IsEnabled())
	{
		// no extrapolation:
		if(m_CamPath.GetLowerBound() <= curTime && curTime <= m_CamPath.GetUpperBound())
		{
			CamPathValue val = m_CamPath.Eval( curTime );

			//Tier0_Msg("================",curTime);
			//Tier0_Msg("currenTime = %f",curTime);
			//Tier0_Msg("vCp = %f %f %f\n", val.X, val.Y, val.Z);

			Tx = (float)val.X;
			Ty = (float)val.Y;
			Tz = (float)val.Z;

			Rx = (float)val.Pitch;
			Ry = (float)val.Yaw;
			Rz = (float)val.Roll;

			Fov = (float)val.Fov;
		}
	}

	if(m_Import) {
		double Tf[6];

		if(g_BvhImport.GetCamPositon(
			curTime -m_ImportBaseTime,
			Tf
		)) {
			Ty = (float)(-Tf[0]);
			Tz = (float)(+Tf[1]);
			Tx = (float)(-Tf[2]);
			Rz = (float)(-Tf[3]);
			Rx = (float)(-Tf[4]);
			Ry = (float)(+Tf[5]);
		}
	}

	if(m_FovOverride) Fov = (float)m_FovValue;

	if(g_AfxHookSourceInput.GetCameraControlMode() && m_Globals)
	{
		double dT = m_Globals->absoluteframetime_get();
		double dForward = dT * g_AfxHookSourceInput.GetCamDForward();
		double dLeft = dT * g_AfxHookSourceInput.GetCamDLeft();
		double dUp = dT * g_AfxHookSourceInput.GetCamDUp();
		double dPitch = dT * g_AfxHookSourceInput.GetCamDPitch();
		double dRoll = dT * g_AfxHookSourceInput.GetCamDRoll();
		double dYaw = dT * g_AfxHookSourceInput.GetCamDYaw();
		double dFov = dT * g_AfxHookSourceInput.GetCamDFov();
		double forward[3], right[3], up[3];

		Rx = (float)(LastCameraAngles[0] +dPitch);
		Ry = (float)(LastCameraAngles[1] +dYaw);
		Rz = (float)(LastCameraAngles[2] +dRoll);
		Fov = (float)(LastCameraFov +dFov);

		if(g_AfxHookSourceInput.GetCamResetView())
		{
			Rx = 0;
			Ry = 0;
			Rz = 0;
			Fov = 90.0;
		}

		MakeVectors(Rz, Rx, Ry, forward, right, up);

		Tx = (float)(LastCameraOrigin[0] + dForward*forward[0] -dLeft*right[0] +dUp*up[0]);
		Ty = (float)(LastCameraOrigin[1] + dForward*forward[1] -dLeft*right[1] +dUp*up[1]);
		Tz = (float)(LastCameraOrigin[2] + dForward*forward[2] -dLeft*right[2] +dUp*up[2]);
	}

	// limit fov to sane values:
	if(Fov<1) Fov = 1;
	else if(Fov>179) Fov = 179;

	if(m_Export) {
		g_BvhExport->WriteFrame(
			-Ty, +Tz, -Tx,
			-Rz, -Rx, +Ry
		);
	}

	LastCameraOrigin[0] = Tx;
	LastCameraOrigin[1] = Ty;
	LastCameraOrigin[2] = Tz;
	LastCameraAngles[0] = Rx;
	LastCameraAngles[1] = Ry;
	LastCameraAngles[2] = Rz;
	LastCameraFov = Fov;

	g_AfxHookSourceInput.Supply_MouseFrameEnd();

	//Tier0_Msg("Hook_VClient_RenderView::OnViewOverride: curTime = %f, LastCameraOrigin=%f,%f,%f\n",curTime,LastCameraOrigin[0],LastCameraOrigin[1],LastCameraOrigin[2]);
}
Esempio n. 9
0
void CCampathDrawer::OnPostRenderAllTools()
{
	// Actually we are often called twice per frame due to an engine bug(?), once after 3d skybox
	// and once after world is drawn, maybe we will be even called more times,
	// but we can not care about that for now.
	
	if(!m_Draw)
		return;

	if(!m_VertexShader)
	{
		m_VertexShader = g_AfxShaders.GetVertexShader("afx_line_vs20.fxo");
	}
	IDirect3DVertexShader9 * vertexShader = m_VertexShader->GetVertexShader();

	if(!m_PixelShader)
	{
		m_PixelShader = g_AfxShaders.GetPixelShader("afx_line_ps20.fxo");
	}
	IDirect3DPixelShader9 * pixelShader = m_PixelShader->GetPixelShader();

	if(!(m_Device && vertexShader && m_PixelShader && g_VEngineClient))
	{
		static bool firstError = true;

		if(firstError)
		{
			firstError = false;
			Tier0_Msg(
				"AFXERROR: CCampathDrawer::OnEndScene: Missing required dependencies:%s%s%s%s.\n",
				!m_Device ? " m_Device" : "",
				!vertexShader ? " vertexShader" : "",
				!pixelShader ? " pixelShader" : "",
				!g_VEngineClient ? " g_VEngineClient" : ""
			);
		}

		return;
	}

	// Save device state:

	IDirect3DPixelShader9 * oldPixelShader = 0;
	m_Device->GetPixelShader(&oldPixelShader);
	if(oldPixelShader) oldPixelShader->AddRef();

	IDirect3DVertexShader9 * oldVertexShader = 0;
	m_Device->GetVertexShader(&oldVertexShader);
	if(oldVertexShader) oldVertexShader->AddRef();

	IDirect3DVertexBuffer9 * oldVertexBuffer = 0;
	UINT oldVertexBufferOffset;
	UINT oldVertexBufferStride;
	m_Device->GetStreamSource(0, &oldVertexBuffer, &oldVertexBufferOffset, &oldVertexBufferStride);
	// this is done already according to doc: // if(oldVertexBuffer) oldVertexBuffer->AddRef();

	IDirect3DIndexBuffer9 * oldIndexBuffer = 0;
	m_Device->GetIndices(&oldIndexBuffer);
	// this is done already according to doc: // if(oldIndexBuffer) oldIndexBuffer->AddRef();

	IDirect3DVertexDeclaration9 * oldDeclaration;
	m_Device->GetVertexDeclaration(&oldDeclaration);
	if(oldDeclaration) oldDeclaration->AddRef();

	DWORD oldFVF;
	m_Device->GetFVF(&oldFVF);

	FLOAT oldCViewProj[4][4];
	m_Device->GetVertexShaderConstantF(8, oldCViewProj[0], 4);

	FLOAT oldCScreenInfo[4];
	m_Device->GetVertexShaderConstantF(48, oldCScreenInfo, 1);

	FLOAT oldCPlane0[4];
	m_Device->GetVertexShaderConstantF(49, oldCPlane0, 1);

	FLOAT oldCPlaneN[4];
	m_Device->GetVertexShaderConstantF(50, oldCPlaneN, 1);

	DWORD oldSrgbWriteEnable;
	m_Device->GetRenderState(D3DRS_SRGBWRITEENABLE, &oldSrgbWriteEnable);

	DWORD oldColorWriteEnable;
	m_Device->GetRenderState(D3DRS_COLORWRITEENABLE, &oldColorWriteEnable);

	DWORD oldZEnable;
	m_Device->GetRenderState(D3DRS_ZENABLE, &oldZEnable);

	DWORD oldZWriteEnable;
	m_Device->GetRenderState(D3DRS_ZWRITEENABLE, &oldZWriteEnable);
	
	DWORD oldZFunc;
	m_Device->GetRenderState(D3DRS_ZFUNC, &oldZFunc);

	DWORD oldAlphaTestEnable;
	m_Device->GetRenderState(D3DRS_ALPHATESTENABLE, &oldAlphaTestEnable);

	DWORD oldSeparateAlphaBlendEnable;
	m_Device->GetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, &oldSeparateAlphaBlendEnable);

	DWORD oldAlphaBlendEnable;
	m_Device->GetRenderState(D3DRS_ALPHABLENDENABLE, &oldAlphaBlendEnable);

	DWORD oldBlendOp;
	m_Device->GetRenderState(D3DRS_BLENDOP, &oldBlendOp);

	DWORD oldSrcBlend;
	m_Device->GetRenderState(D3DRS_SRCBLEND, &oldSrcBlend);

	DWORD oldDestBlend;
	m_Device->GetRenderState(D3DRS_DESTBLEND, &oldDestBlend);

	DWORD oldCullMode;
	m_Device->GetRenderState(D3DRS_CULLMODE, &oldCullMode);

	// Draw:
	{
		//Vector3 vvForward, vvUp, vvRight, vvPos;

		double curTime = g_Hook_VClient_RenderView.GetCurTime();
		bool inCampath = 1 <= g_Hook_VClient_RenderView.m_CamPath.GetSize()
			&&	g_Hook_VClient_RenderView.m_CamPath.GetLowerBound() <= curTime
			&& curTime <= g_Hook_VClient_RenderView.m_CamPath.GetUpperBound();
		bool campathCanEval = g_Hook_VClient_RenderView.m_CamPath.CanEval();
		bool campathEnabled = g_Hook_VClient_RenderView.m_CamPath.Enabled_get();
		bool cameraMightBeSelected = false;

		m_Device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
		m_Device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED);
		m_Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
		m_Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
		m_Device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
		m_Device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
		m_Device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
		m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
		m_Device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
		m_Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		m_Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
		m_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

		m_Device->SetVertexShader(vertexShader);

		m_WorldToScreenMatrix = g_VEngineClient->WorldToScreenMatrix();
			
		m_Device->SetVertexShaderConstantF(8, m_WorldToScreenMatrix.m[0], 4);

		// Provide view plane info for line clipping:
		{
			double plane0[4]={0,0,0,1};
			double planeN[4]={1,0,0,1};
			//double planeR[4]={0,-1,0,1};
			//double planeU[4]={0,0,1,1};

			unsigned char P[4];
			unsigned char Q[4];

			double L[4][4];
			double U[4][4];

			double M[4][4] = {
				m_WorldToScreenMatrix.m[0][0], m_WorldToScreenMatrix.m[0][1], m_WorldToScreenMatrix.m[0][2], 0,
				m_WorldToScreenMatrix.m[1][0], m_WorldToScreenMatrix.m[1][1], m_WorldToScreenMatrix.m[1][2], 0,
				m_WorldToScreenMatrix.m[2][0], m_WorldToScreenMatrix.m[2][1], m_WorldToScreenMatrix.m[2][2], 0,
				m_WorldToScreenMatrix.m[3][0], m_WorldToScreenMatrix.m[3][1], m_WorldToScreenMatrix.m[3][2], -1,
			};

			double b0[4] = {
				0 -m_WorldToScreenMatrix.m[0][3],
				0 -m_WorldToScreenMatrix.m[1][3],
				0 -m_WorldToScreenMatrix.m[2][3],
				-m_WorldToScreenMatrix.m[3][3],
			};

			double bN[4] = {
				0 -m_WorldToScreenMatrix.m[0][3],
				0 -m_WorldToScreenMatrix.m[1][3],
				1 -m_WorldToScreenMatrix.m[2][3],
				-m_WorldToScreenMatrix.m[3][3],
			};
			/*
			double bR[4] = {
				1 -m_WorldToScreenMatrix.m[0][3],
				0 -m_WorldToScreenMatrix.m[1][3],
				0 -m_WorldToScreenMatrix.m[2][3],
				-m_WorldToScreenMatrix.m[3][3],
			};

			double bU[4] = {
				0 -m_WorldToScreenMatrix.m[0][3],
				1 -m_WorldToScreenMatrix.m[1][3],
				0 -m_WorldToScreenMatrix.m[2][3],
				-m_WorldToScreenMatrix.m[3][3],
			};
			*/
			if(!LUdecomposition(M, P, Q, L, U))
			{
				Tier0_Warning("AFXERROR in CCampathDrawer::OnPostRenderAllTools: LUdecomposition failed\n");
			}
			else
			{
				SolveWithLU(L, U, P, Q, b0, plane0);
				SolveWithLU(L, U, P, Q, bN, planeN);
				
				//SolveWithLU(L, U, P, Q, bR, planeR);
				//SolveWithLU(L, U, P, Q, bU, planeU);
			}

			/*
			vvPos = Vector3(plane0[0], plane0[1], plane0[2]);
			vvForward = Vector3(planeN[0] -vvPos.X, planeN[1] -vvPos.Y, planeN[2]-vvPos.Z);
			vvForward.Normalize();
			vvRight = Vector3(planeR[0] -vvPos.X, planeR[1] -vvPos.Y, planeR[2]-vvPos.Z);
			vvRight.Normalize();
			vvUp = Vector3(planeU[0] -vvPos.X, planeU[1] -vvPos.Y, planeU[2]-vvPos.Z);
			vvUp.Normalize();
			*/

			/*
			Tier0_Msg("CCampathDrawer::OnPostRenderAllTools: curTime = %f\n",curTime);
			Tier0_Msg("M[0]=%f %f %f %f\nM[1]=%f %f %f %f\nM[2]=%f %f %f %f\nM[3]=%f %f %f %f\n", M[0][0],M[0][1],M[0][2],M[0][3], M[1][0],M[1][1],M[1][2],M[1][3], M[2][0],M[2][1],M[2][2],M[2][3], M[3][0],M[3][1],M[3][2],M[3][3]);
			Tier0_Msg("b0[0]=%f %f %f %f\n", b0[0], b0[1], b0[2], b0[3]);
			Tier0_Msg("bN[0]=%f %f %f %f\n", bN[0], bN[1], bN[2], bN[3]);
			Tier0_Msg("plane0=%f %f %f %f\n", plane0[0], plane0[1], plane0[2], plane0[3]);
			Tier0_Msg("planeN=%f %f %f %f\n", planeN[0], planeN[1], planeN[2], planeN[3]);
			*/

			FLOAT vPlane0[4] = {(float)plane0[0], (float)plane0[1], (float)plane0[2], 0.0f};

			Vector3 planeNormal(planeN[0] -plane0[0], planeN[1] -plane0[1], planeN[2] -plane0[2]);
			planeNormal.Normalize();

			FLOAT vPlaneN[4] = {(float)planeNormal.X, (float)planeNormal.Y, (float)planeNormal.Z, 0.0f};

			m_Device->SetVertexShaderConstantF(49, vPlane0, 1);
			m_Device->SetVertexShaderConstantF(50, vPlaneN, 1);
		}

		m_Device->SetPixelShader(pixelShader);

		m_Device->SetFVF(CCampathDrawer_VertexFVF);

		int screenWidth, screenHeight;
		g_VEngineClient->GetScreenSize(screenWidth, screenHeight);
		FLOAT newCScreenInfo[4] = { 0 != screenWidth ? 1.0f / screenWidth : 0.0f, 0 != screenHeight ? 1.0f / screenHeight : 0.0f, 0.0, 0.0f};

		// Draw trajectory:
		if(2 <= g_Hook_VClient_RenderView.m_CamPath.GetSize() && campathCanEval)
		{
			if(m_RebuildDrawing)
			{
				// Rebuild trajectory points.
				// This operation can be quite expensive (up to O(N^2)),
				// so it should be done only when s.th.
				// changed (which is what we do here).

				m_TrajectoryPoints.clear();
				
				CamPathIterator last = g_Hook_VClient_RenderView.m_CamPath.GetBegin();				
				CamPathIterator it = last;

				TempPoint * pts = new TempPoint[c_CameraTrajectoryMaxPointsPerInterval];

				for(++it; it != g_Hook_VClient_RenderView.m_CamPath.GetEnd(); ++it)
				{
					double delta = it.GetTime() -last.GetTime();

					for(size_t i = 0; i<c_CameraTrajectoryMaxPointsPerInterval; i++)
					{
						double t = last.GetTime() + delta*((double)i/(c_CameraTrajectoryMaxPointsPerInterval-1));

						CamPathValue cpv = g_Hook_VClient_RenderView.m_CamPath.Eval(t);

						pts[i].t = t;
						pts[i].y = Vector3(cpv.X, cpv.Y, cpv.Z);
						pts[i].nextPt = i+1 <c_CameraTrajectoryMaxPointsPerInterval ? &(pts[i+1]) : 0;
					}

					RamerDouglasPeucker(&(pts[0]), &(pts[c_CameraTrajectoryMaxPointsPerInterval-1]), c_CameraTrajectoryEpsilon);

					// add all points except the last one (to avoid duplicates):
					for(TempPoint * pt = &(pts[0]); pt && pt->nextPt; pt = pt->nextPt)
					{
						m_TrajectoryPoints.push_back(pt->t);
					}

					last = it;
				}

				// add last point:
				m_TrajectoryPoints.push_back(pts[c_CameraTrajectoryMaxPointsPerInterval-1].t);

				delete pts;

				m_RebuildDrawing = false;
			}

			newCScreenInfo[2] = c_CameraTrajectoryPixelWidth;
			m_Device->SetVertexShaderConstantF(48, newCScreenInfo, 1);

			AutoPolyLineStart();

			std::list<double>::iterator itPts = m_TrajectoryPoints.begin();

			CamPathIterator itKeysLast = g_Hook_VClient_RenderView.m_CamPath.GetBegin();
			CamPathIterator itKeysNext = itKeysLast;
			++itKeysNext;

			bool hasLastPt = false;
			bool hasNextPt = false;
			bool hasCurPt = false;
			
			double lastPtTime;
			CamPathValue lastPtValue;
			double curPtTime;
			CamPathValue curPtValue;
			double nextPtTime;
			CamPathValue nextPtValue;

			do
			{
				if(hasNextPt)
				{
					hasLastPt = true;
					lastPtTime = curPtTime;
					lastPtValue = curPtValue;

					hasCurPt = true;
					curPtTime = nextPtTime;
					curPtValue = nextPtValue;

					hasNextPt = false;
				}
				else
				{
					hasCurPt = true;
					curPtTime = *itPts;
					curPtValue = g_Hook_VClient_RenderView.m_CamPath.Eval(curPtTime);
					++itPts;
				}

				while(itKeysNext.GetTime() < curPtTime)
				{
					itKeysLast = itKeysNext;
					++itKeysNext;
				}

				if(itPts != m_TrajectoryPoints.end())
				{
					hasNextPt = true;
					nextPtTime = *itPts;
					nextPtValue = g_Hook_VClient_RenderView.m_CamPath.Eval(nextPtTime);
					++itPts;
				}
				else
				{
					// current point is last point.
					hasNextPt = false;
					nextPtValue = curPtValue;
				}

				if(!hasLastPt)
				{
					// current point is first point.
					lastPtValue = curPtValue;
				}

				// emit current point:
				{
					double deltaTime = abs(curTime -curPtTime);

					DWORD colour;

					// determine colour:
					if(deltaTime < 1.0)
					{
						double t = (deltaTime -0.0)/1.0;
						colour = D3DCOLOR_RGBA(
							ValToUCCondInv(255.0*t, curPtValue.Selected),
							ValToUCCondInv(255, curPtValue.Selected),
							ValToUCCondInv(0, curPtValue.Selected),
							(unsigned char)(127*(1.0-t))+128
						);
					}
					else
					if(deltaTime < 2.0)
					{
						double t = (deltaTime -1.0)/1.0;
						colour = D3DCOLOR_RGBA(
							ValToUCCondInv(255, curPtValue.Selected),
							ValToUCCondInv(255.0*(1.0-t), curPtValue.Selected),
							ValToUCCondInv(0, curPtValue.Selected),
							(unsigned char)(64*(1.0-t))+64
						);
					}
					else
					{
						colour = D3DCOLOR_RGBA(
							ValToUCCondInv(255, curPtValue.Selected),
							ValToUCCondInv(0, curPtValue.Selected),
							ValToUCCondInv(0, curPtValue.Selected),
							64
						);
					}

					AutoPolyLinePoint(
						Vector3(lastPtValue.X,lastPtValue.Y,lastPtValue.Z)
						, Vector3(curPtValue.X,curPtValue.Y,curPtValue.Z)
						, colour
						, Vector3(nextPtValue.X,nextPtValue.Y,nextPtValue.Z));
				}
			}
			while(hasNextPt);

			AutoPolyLineFlush();
		}

		// Draw keyframes:
		{
			newCScreenInfo[2] = c_CampathCrossPixelWidth;
			m_Device->SetVertexShaderConstantF(48, newCScreenInfo, 1);

			bool lpSelected = false;
			double lpTime;
			
			/*if(0 < g_Hook_VClient_RenderView.m_CamPath.GetSize())
			{
				// Test for not too unlikely hard case:
				CamPathValue cpv = g_Hook_VClient_RenderView.m_CamPath.GetBegin().GetValue();
				Vector3 current(cpv.X+76, cpv.Y+76, cpv.Z+76);
				Vector3 previous(current.X+76, current.Y-1*4, current.Z);
				Vector3 next(current.X+76, current.Y+1*4, current.Z);
				Vector3 next2(current.X, current.Y+2*4, current.Z);
				Vector3 next3(current.X+76, current.Y+3*4, current.Z);
				Vector3 next4(current.X, current.Y+4*4, current.Z);
				Vector3 next5(current.X+76, current.Y+5*4, current.Z);

				AutoPolyLineStart();
				AutoPolyLinePoint(previous, previous, D3DCOLOR_RGBA(255,0,0,255), current);
				AutoPolyLinePoint(previous, current, D3DCOLOR_RGBA(255,0,0,255), next);
				AutoPolyLinePoint(current, next, D3DCOLOR_RGBA(255,0,0,255), next2);
				AutoPolyLinePoint(next, next2, D3DCOLOR_RGBA(255,0,0,255), next3);
				AutoPolyLinePoint(next2, next3, D3DCOLOR_RGBA(255,0,0,255), next4);
				AutoPolyLinePoint(next3, next4, D3DCOLOR_RGBA(255,0,0,255), next5);
				AutoPolyLinePoint(next4, next5, D3DCOLOR_RGBA(255,0,0,255), next5);
				AutoPolyLineFlush();
			}*/
			
			/*if(0 < g_Hook_VClient_RenderView.m_CamPath.GetSize())
			{
				CamPathValue cpv = g_Hook_VClient_RenderView.m_CamPath.GetBegin().GetValue();

				float x = cpv.X * m_WorldToScreenMatrix.m[0][0] + cpv.Y * m_WorldToScreenMatrix.m[0][1] + cpv.Z * m_WorldToScreenMatrix.m[0][2] +m_WorldToScreenMatrix.m[0][3];
				float y = cpv.X * m_WorldToScreenMatrix.m[1][0] + cpv.Y * m_WorldToScreenMatrix.m[1][1] + cpv.Z * m_WorldToScreenMatrix.m[1][2] +m_WorldToScreenMatrix.m[1][3];
				float z = cpv.X * m_WorldToScreenMatrix.m[2][0] + cpv.Y * m_WorldToScreenMatrix.m[2][1] + cpv.Z * m_WorldToScreenMatrix.m[2][2] +m_WorldToScreenMatrix.m[2][3];
				float w = cpv.X * m_WorldToScreenMatrix.m[3][0] + cpv.Y * m_WorldToScreenMatrix.m[3][1] + cpv.Z * m_WorldToScreenMatrix.m[3][2] +m_WorldToScreenMatrix.m[3][3];

				float iw = w ? 1/w : 0;

				Tier0_Msg("pt: %f %f %f %f -> %f %f %f %f\n",x,y,z,w,x*iw,y*iw,z*iw,w*iw);
			}*/
		
			for(CamPathIterator it = g_Hook_VClient_RenderView.m_CamPath.GetBegin(); it != g_Hook_VClient_RenderView.m_CamPath.GetEnd(); ++it)
			{
				double cpT = it.GetTime();
				CamPathValue cpv = it.GetValue();

				cameraMightBeSelected = cameraMightBeSelected || lpSelected && cpv.Selected && lpTime <= curTime && curTime <= cpT;

				lpSelected = cpv.Selected;
				lpTime = cpT;

				double deltaTime = abs(curTime -cpT);

				bool selected = cpv.Selected;

				DWORD colour;

				// determine colour:
				if(deltaTime < 1.0)
				{
					double t = (deltaTime -0.0)/1.0;
					colour = D3DCOLOR_RGBA(
						ValToUCCondInv(255.0*t, selected),
						ValToUCCondInv(255, selected),
						ValToUCCondInv(0, selected),
						(unsigned char)(127*(1.0-t))+128
					);
				}
				else
				if(deltaTime < 2.0)
				{
					double t = (deltaTime -1.0)/1.0;
					colour = D3DCOLOR_RGBA(
						ValToUCCondInv(255, selected),
						ValToUCCondInv(255.0*(1.0-t), selected),
						ValToUCCondInv(0, selected),
						(unsigned char)(64*(1.0-t))+64
					);
				}
				else
				{
					colour = D3DCOLOR_RGBA(
						ValToUCCondInv(255, selected),
						ValToUCCondInv(0, selected),
						ValToUCCondInv(0, selected),
						64
					);
				}

				// x / forward line:

				AutoSingleLine(
					Vector3(cpv.X -c_CampathCrossRadius, cpv.Y, cpv.Z),
					colour,
					Vector3(cpv.X +c_CampathCrossRadius, cpv.Y, cpv.Z),
					colour
				);

				// y / left line:

				AutoSingleLine(
					Vector3(cpv.X, cpv.Y -c_CampathCrossRadius, cpv.Z),
					colour,
					Vector3(cpv.X, cpv.Y +c_CampathCrossRadius, cpv.Z),
					colour
				);

				// z / up line:

				AutoSingleLine(
					Vector3(cpv.X, cpv.Y, cpv.Z -c_CampathCrossRadius),
					colour,
					Vector3(cpv.X, cpv.Y, cpv.Z +c_CampathCrossRadius),
					colour
				);
			}

			AutoSingleLineFlush();
		}

		// Draw wireframe camera:
		if(inCampath && campathCanEval)
		{
			newCScreenInfo[2] = c_CameraPixelWidth;
			m_Device->SetVertexShaderConstantF(48, newCScreenInfo, 1);

			DWORD colourCam = campathEnabled
				? D3DCOLOR_RGBA(
					ValToUCCondInv(255,cameraMightBeSelected),
					ValToUCCondInv(0,cameraMightBeSelected),
					ValToUCCondInv(255,cameraMightBeSelected),
					128)
				: D3DCOLOR_RGBA(
					ValToUCCondInv(255,cameraMightBeSelected),
					ValToUCCondInv(255,cameraMightBeSelected),
					ValToUCCondInv(255,cameraMightBeSelected),
					128);
			DWORD colourCamUp = campathEnabled
				? D3DCOLOR_RGBA(
					ValToUCCondInv(0,cameraMightBeSelected),
					ValToUCCondInv(255,cameraMightBeSelected),
					ValToUCCondInv(0,cameraMightBeSelected),
					128)
				: D3DCOLOR_RGBA(
					ValToUCCondInv(0,cameraMightBeSelected),
					ValToUCCondInv(0,cameraMightBeSelected),
					ValToUCCondInv(0,cameraMightBeSelected),
					128);

			CamPathValue cpv = g_Hook_VClient_RenderView.m_CamPath.Eval(curTime);

			// limit to values as RenderView hook:
			cpv.Fov = max(1,cpv.Fov);
			cpv.Fov = min(179,cpv.Fov);

			double forward[3], right[3], up[3];
			QEulerAngles ang = cpv.R.ToQREulerAngles().ToQEulerAngles();
			MakeVectors(ang.Roll, ang.Pitch, ang.Yaw, forward, right, up);

			Vector3 vCp(cpv.X, cpv.Y, cpv.Z);
			Vector3 vForward(forward);
			Vector3 vUp(up);
			Vector3 vRight(right);

			//Tier0_Msg("----------------",curTime);
			//Tier0_Msg("currenTime = %f",curTime);
			//Tier0_Msg("vCp = %f %f %f\n", vCp.X, vCp.Y, vCp.Z);

			double a = sin(cpv.Fov * M_PI / 360.0) * c_CameraRadius;
			double b = a;

			int screenWidth, screenHeight;
			g_VEngineClient->GetScreenSize(screenWidth, screenHeight);

			double aspectRatio = screenWidth ? (double)screenHeight / (double)screenWidth : 1.0;

			b *= aspectRatio;

			Vector3 vLU = vCp +(double)c_CameraRadius * vForward -a * vRight +b * vUp;
			Vector3 vRU = vCp +(double)c_CameraRadius * vForward +a * vRight +b * vUp;
			Vector3 vLD = vCp +(double)c_CameraRadius * vForward -a * vRight -b * vUp;
			Vector3 vRD = vCp +(double)c_CameraRadius * vForward +a * vRight -b * vUp;
			Vector3 vMU = vLU +(vRU -vLU)/2;
			Vector3 vMUU = vMU +(double)c_CameraRadius * vUp;

			AutoSingleLine(vCp, colourCam, vLD, colourCam);

			AutoSingleLine(vCp, colourCam, vRD, colourCam);

			AutoSingleLine(vCp, colourCam, vLU, colourCam);

			AutoSingleLine(vCp, colourCam, vRU, colourCam);

			AutoSingleLine(vLD, colourCam, vRD, colourCam);

			AutoSingleLine(vRD, colourCam, vRU, colourCam);

			AutoSingleLine(vRU, colourCam, vLU, colourCam);

			AutoSingleLine(vLU, colourCam, vLD, colourCam);

			AutoSingleLine(vMU, colourCam, vMUU, colourCamUp);

			AutoSingleLineFlush();

			//
			/*

			colourCam = D3DCOLOR_RGBA(255, 0, 0, 255);
			colourCamUp = D3DCOLOR_RGBA(255, 255, 0, 255);

			vCp = vvPos;
			vForward = vvForward;
			vUp = vvUp;
			vRight = vvRight;

			//Tier0_Msg("vCp2 = %f %f %f\n", vCp.X, vCp.Y, vCp.Z);

			vLU = vCp +(double)c_CameraRadius * vForward -a * vRight +b * vUp;
			vRU = vCp +(double)c_CameraRadius * vForward +a * vRight +b * vUp;
			vLD = vCp +(double)c_CameraRadius * vForward -a * vRight -b * vUp;
			vRD = vCp +(double)c_CameraRadius * vForward +a * vRight -b * vUp;
			vMU = vLU +(vRU -vLU)/2;
			vMUU = vMU +(double)c_CameraRadius * vUp;

			AutoSingleLine(vCp, colourCam, vLD, colourCam);

			AutoSingleLine(vCp, colourCam, vRD, colourCam);

			AutoSingleLine(vCp, colourCam, vLU, colourCam);

			AutoSingleLine(vCp, colourCam, vRU, colourCam);

			AutoSingleLine(vLD, colourCam, vRD, colourCam);

			AutoSingleLine(vRD, colourCam, vRU, colourCam);

			AutoSingleLine(vRU, colourCam, vLU, colourCam);

			AutoSingleLine(vLU, colourCam, vLD, colourCam);

			AutoSingleLine(vMU, colourCam, vMUU, colourCamUp);

			AutoSingleLineFlush();
			*/
		}
	}

	// Restore device state:

	m_Device->SetPixelShader(oldPixelShader);
	if(oldPixelShader) oldPixelShader->Release();

	m_Device->SetVertexShader(oldVertexShader);
	if(oldVertexShader) oldVertexShader->Release();

	m_Device->SetStreamSource(0, oldVertexBuffer, oldVertexBufferOffset, oldVertexBufferStride);
	if(oldVertexBuffer) oldVertexBuffer->Release();

	m_Device->SetIndices(oldIndexBuffer);
	if(oldIndexBuffer) oldIndexBuffer->Release();

	m_Device->SetFVF(oldFVF);

	m_Device->SetVertexDeclaration(oldDeclaration);
	if(oldDeclaration) oldDeclaration->Release();

	m_Device->SetVertexShaderConstantF(8, oldCViewProj[0], 4);
	m_Device->SetVertexShaderConstantF(48, oldCScreenInfo, 1);
	m_Device->SetVertexShaderConstantF(49, oldCPlane0, 1);
	m_Device->SetVertexShaderConstantF(50, oldCPlaneN, 1);

	m_Device->SetRenderState(D3DRS_CULLMODE, oldCullMode);
	m_Device->SetRenderState(D3DRS_DESTBLEND, oldDestBlend);
	m_Device->SetRenderState(D3DRS_SRCBLEND, oldSrcBlend);
	m_Device->SetRenderState(D3DRS_BLENDOP, oldBlendOp);
	m_Device->SetRenderState(D3DRS_ALPHABLENDENABLE, oldAlphaBlendEnable);
	m_Device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, oldSeparateAlphaBlendEnable);
	m_Device->SetRenderState(D3DRS_ALPHATESTENABLE, oldAlphaTestEnable);
	m_Device->SetRenderState(D3DRS_ZFUNC, oldZFunc);
	m_Device->SetRenderState(D3DRS_ZWRITEENABLE, oldZWriteEnable);
	m_Device->SetRenderState(D3DRS_ZENABLE, oldZEnable);
	m_Device->SetRenderState(D3DRS_COLORWRITEENABLE, oldColorWriteEnable);
	m_Device->SetRenderState(D3DRS_SRGBWRITEENABLE, oldSrgbWriteEnable);
}
Esempio n. 10
0
void NPC::CheckStuck(float oldSpeed)
{
	if (!IsOnFloor(GetEntity()) || IsOnLadder (GetEntity ()))
		return;

	if (WalkMove())
		return;

	if (m_checkStuckTime > gpGlobals->time)
		return;

	m_checkStuckTime = gpGlobals->time + 0.5f;

	bool isStuck = false;
	float moveDistance = GetDistance(pev->origin, m_prevOrigin);

	if (oldSpeed >= 10.0f && pev->speed >= 10.0f)
	{
		if (moveDistance <= 2.0f)
			isStuck = true;
	}

	if (isStuck)
	{
		MakeVectors(pev->angles);

		TraceResult tr;
		Vector dest = pev->origin;
		dest.z += 32;
		Vector src = pev->origin + gpGlobals->v_forward * 32;

		UTIL_TraceHull(dest, src, dont_ignore_monsters, head_hull, GetEntity(), &tr);
		if (tr.flFraction > 0.0f && tr.flFraction != 1.0f)
		{
			float newOriginZ = pev->origin.z + (tr.vecEndPos.z - GetBottomOrigin(GetEntity ()).z) - 32;
			if (newOriginZ > pev->origin.z && (newOriginZ - pev->origin.z) <= 32)
			{
				pev->velocity.z = (270.0f * pev->gravity) + 32.0f;
				m_jumpAction = false;

				goto end;
			}
		}

		for (int i = 0; i <= 18; i++)
		{
			UTIL_TraceHull(pev->origin, pev->origin, dont_ignore_monsters, human_hull, GetEntity(), &tr);
			if (!tr.fStartSolid && !tr.fAllSolid && tr.fInOpen)
				break;

			if (i == 17)
			{
				int block = MF_ExecuteForward(g_callStuck_Pre, (cell)ENTINDEX(GetEntity()));
				if (!block)
				{
					LogToFile("The NPC is stuck, remove now");
					m_needRemove = true;
				}

				break;
			}

			pev->origin.z += 1;
		}
		
		m_goalWaypoint = -1;
		m_currentWaypointIndex = -1;
		DeleteSearchNodes();
	}

	end: m_prevOrigin = pev->origin;
}
Esempio n. 11
0
void Hook_VClient_RenderView::OnViewOverride(float &Tx, float &Ty, float &Tz, float &Rx, float &Ry, float &Rz, float &Fov)
{
	bool originOrAnglesOverriden = false;

	float curTime = g_MirvTime.GetTime();

	GameCameraOrigin[0] = Tx;
	GameCameraOrigin[1] = Ty;
	GameCameraOrigin[2] = Tz;
	GameCameraAngles[0] = Rx;
	GameCameraAngles[1] = Ry;
	GameCameraAngles[2] = Rz;
	GameCameraFov = Fov;

	if (g_MirvCam.ApplySource(Tx, Ty, Tz, Rz, Rx, Ry)) originOrAnglesOverriden = true;

	if(m_CamPath.Enabled_get() && m_CamPath.CanEval())
	{
		// no extrapolation:
		if(m_CamPath.GetLowerBound() <= curTime && curTime <= m_CamPath.GetUpperBound())
		{
			CamPathValue val = m_CamPath.Eval( curTime );
			QEulerAngles ang = val.R.ToQREulerAngles().ToQEulerAngles();

			//Tier0_Msg("================",curTime);
			//Tier0_Msg("currenTime = %f",curTime);
			//Tier0_Msg("vCp = %f %f %f\n", val.X, val.Y, val.Z);

			originOrAnglesOverriden = true;

			Tx = (float)val.X;
			Ty = (float)val.Y;
			Tz = (float)val.Z;

			Rx = (float)ang.Pitch;
			Ry = (float)ang.Yaw;
			Rz = (float)ang.Roll;

			Fov = (float)val.Fov;
		}
	}

	if(m_Import) {
		double Tf[6];

		if(g_BvhImport.GetCamPosition(
			curTime -m_ImportBaseTime,
			Tf
		)) {
			originOrAnglesOverriden = true;

			Ty = (float)(-Tf[0]);
			Tz = (float)(+Tf[1]);
			Tx = (float)(-Tf[2]);
			Rz = (float)(-Tf[3]);
			Rx = (float)(-Tf[4]);
			Ry = (float)(+Tf[5]);
		}
	}

	if (m_CamImport)
	{
		CamIO::CamData camData;

		if (m_CamImport->GetCamData(curTime, LastWidth, LastHeight, camData))
		{
			originOrAnglesOverriden = true;

			Tx = (float)camData.XPosition;
			Ty = (float)camData.YPosition;
			Tz = (float)camData.ZPosition;
			Rx = (float)camData.YRotation;
			Ry = (float)camData.ZRotation;
			Rz = (float)camData.XRotation;
			Fov = (float)camData.Fov;
		}
	}

	if(m_FovOverride && (!handleZoomEnabled || handleZoomMinUnzoomedFov <= Fov)) Fov = (float)m_FovValue;

	if(g_AfxHookSourceInput.GetCameraControlMode() && m_Globals)
	{
		originOrAnglesOverriden = true;

		double dT = m_Globals->absoluteframetime_get();
		double dForward = dT * g_AfxHookSourceInput.GetCamDForward();
		double dLeft = dT * g_AfxHookSourceInput.GetCamDLeft();
		double dUp = dT * g_AfxHookSourceInput.GetCamDUp();
		double dPitch = dT * g_AfxHookSourceInput.GetCamDPitch();
		double dRoll = dT * g_AfxHookSourceInput.GetCamDRoll();
		double dYaw = dT * g_AfxHookSourceInput.GetCamDYaw();
		double dFov = dT * g_AfxHookSourceInput.GetCamDFov();
		double forward[3], right[3], up[3];

		Rx = (float)(LastCameraAngles[0] +dPitch);
		Ry = (float)(LastCameraAngles[1] +dYaw);
		Rz = (float)(LastCameraAngles[2] +dRoll);
		Fov = (float)(LastCameraFov +dFov);

		if(g_AfxHookSourceInput.GetCamResetView())
		{
			Rx = 0;
			Ry = 0;
			Rz = 0;
			Fov = 90.0;
		}

		MakeVectors(Rz, Rx, Ry, forward, right, up);

		Tx = (float)(LastCameraOrigin[0] + dForward*forward[0] -dLeft*right[0] +dUp*up[0]);
		Ty = (float)(LastCameraOrigin[1] + dForward*forward[1] -dLeft*right[1] +dUp*up[1]);
		Tz = (float)(LastCameraOrigin[2] + dForward*forward[2] -dLeft*right[2] +dUp*up[2]);
	}

	// limit fov to sane values:
	if(Fov<1) Fov = 1;
	else if(Fov>179) Fov = 179;

	if(m_Globals)
	{
		double dRx = Rx;
		double dRy = Ry;
		double dRz = Rz;

		if(g_Aiming.Aim(m_Globals->absoluteframetime_get(), Vector3(Tx, Ty, Tz), dRx, dRy, dRz))
		{
			originOrAnglesOverriden = true;
			
			Rx = (float)dRx;
			Ry = (float)dRy;
			Rz = (float)dRz;
		}
	}

	if (g_MirvCam.ApplyOffset(Tx, Ty, Tz, Rz, Rx, Ry)) originOrAnglesOverriden = true;

	g_MirvCam.ApplyFov(Fov);

#ifdef AFX_INTEROP
	if(AfxInterop::OnRenderView(Tx, Ty, Tz, Rx, Ry, Rz, Fov)) originOrAnglesOverriden = true;
#endif
	
	static bool viewOverriding = false;

	if (originOrAnglesOverriden && this->ForceViewOverride)
	{
		TrySetView(Tx, Ty, Tz, Rx, Ry, Rz, Fov, nullptr, nullptr);

		viewOverriding = true;
	}
	else if (viewOverriding)
	{
		viewOverriding = false;

		if (this->ViewOverrideReset)
		{
			TrySetView(Tx, Ty, Tz, Rx, Ry, 0.0f, 90.0f, nullptr, nullptr);
		}
	}


	if(m_Export) {
		g_BvhExport->WriteFrame(
			-Ty, +Tz, -Tx,
			-Rz, -Rx, +Ry
		);
	}

	if (m_CamExport)
	{
		CamIO::CamData camData;

		camData.Time = curTime;
		camData.XPosition = Tx;
		camData.YPosition = Ty;
		camData.ZPosition = Tz;
		camData.YRotation = Rx;
		camData.ZRotation = Ry;
		camData.XRotation = Rz;
		camData.Fov = Fov;

		m_CamExport->WriteFrame(LastWidth, LastHeight, camData);
	}

	LastCameraOrigin[0] = Tx;
	LastCameraOrigin[1] = Ty;
	LastCameraOrigin[2] = Tz;
	LastCameraAngles[0] = Rx;
	LastCameraAngles[1] = Ry;
	LastCameraAngles[2] = Rz;
	LastCameraFov = Fov;

	g_AfxHookSourceInput.Supply_MouseFrameEnd();

	//Tier0_Msg("Hook_VClient_RenderView::OnViewOverride: curTime = %f, LastCameraOrigin=%f,%f,%f\n",curTime,LastCameraOrigin[0],LastCameraOrigin[1],LastCameraOrigin[2]);
}
Esempio n. 12
0
// SyPB Pro P.30 - Attack Ai
void Bot::CombatFight(void)
{
	if (FNullEnt(m_enemy))
		return;

	//if (m_currentWeapon == WEAPON_KNIFE)

	// SyPB Pro P.34 - Base Ai
	m_destOrigin = GetEntityOrigin(m_enemy);

	// SyPB Pro P.30 - Zombie Mod
	if (GetGameMod() == 2 || GetGameMod () == 4) // SyPB Pro P.37 - small change
	{
		m_currentWaypointIndex = -1;
		m_prevGoalIndex = -1;
		m_moveToGoal = false;
		m_navTimeset = engine->GetTime();
		
		if (IsZombieBot(GetEntity()))
		{
			m_moveSpeed = pev->maxspeed; 
			return;
		}
	}

	Vector enemyOrigin = GetEntityOrigin(m_enemy);
	float distance = (pev->origin - enemyOrigin).GetLength();

	if (m_timeWaypointMove + m_frameInterval < engine->GetTime())
	{
		if (GetGameMod() == 2)
		{
			float baseDistance = 600.0f;

			if (::IsInViewCone(pev->origin, m_enemy) && 
				GetNearbyEnemiesNearPosition (GetEntityOrigin (m_enemy), 300) < 3) // SyPB Pro P.37 - Zombie Mode Attack Ai
			{
				if (m_currentWeapon == WEAPON_KNIFE)
					baseDistance = 450.0f;
				else
					baseDistance = 400.0f;
			}
			else
			{
				if (m_currentWeapon == WEAPON_KNIFE)
					baseDistance = -1.0f;
				else
					baseDistance = 300.0f;
			}

			if (baseDistance != -1.0f)
			{
				int fdPlayer = GetNearbyFriendsNearPosition(pev->origin, (baseDistance > 0.0f) ? int(baseDistance) / 2 : 300);
				int enPlayer = GetNearbyEnemiesNearPosition(enemyOrigin, (baseDistance > 0.0f) ? int(baseDistance) : 400);

				baseDistance -= (fdPlayer * 10.0f);
				baseDistance += (enPlayer * 20.0f);

				if (baseDistance <= 0.0f)
					baseDistance = 50.0f;
			}

			if (baseDistance < 0.0f)
				m_moveSpeed = pev->maxspeed;
			else
			{
				if (distance <= baseDistance)
					m_moveSpeed = -pev->maxspeed;
				else if (distance >= (baseDistance + 100.0f))
					m_moveSpeed = 0.0f;
			}

			if (m_moveSpeed > 0.0f)
			{
				if (baseDistance != -1.0f)
				{
					if (distance <= 100)
						m_moveSpeed = -pev->maxspeed;
					else
						m_moveSpeed = 0.0f;
				}
			}
		}
		else if (GetGameMod() == 1)
		{
			if (m_currentWeapon == WEAPON_KNIFE)
				m_moveSpeed = pev->maxspeed;
			else
				m_moveSpeed = 0.0f;
		}
		else
		{
			int approach;

			if ((m_states & STATE_SUSPECTENEMY) && !(m_states & STATE_SEEINGENEMY)) // if suspecting enemy stand still
				approach = 49;
			else if (m_isReloading || m_isVIP) // if reloading or vip back off
				approach = 29;
			else if (m_currentWeapon == WEAPON_KNIFE) // knife?
				approach = 100;
			else
			{
				approach = static_cast <int> (pev->health * m_agressionLevel);

				if (UsesSniper() && (approach > 49))
					approach = 49;

				// SyPB Pro P.35 - Base mode Weapon Ai Improve
				if (UsesSubmachineGun())
					approach += 20;
			}
			
			// only take cover when bomb is not planted and enemy can see the bot or the bot is VIP
			if (approach < 30 && !g_bombPlanted && (::IsInViewCone(pev->origin, m_enemy) && !UsesSniper () || m_isVIP))
			{
				m_moveSpeed = -pev->maxspeed;

				GetCurrentTask()->taskID = TASK_SEEKCOVER;
				GetCurrentTask()->canContinue = true;
				GetCurrentTask()->desire = TASKPRI_FIGHTENEMY + 1.0f;
			}
			else if (approach < 50)
				m_moveSpeed = 0.0f;
			else
				m_moveSpeed = pev->maxspeed;

			// SyPB Pro P.35 - Base mode Weapon Ai Improve
			if (distance < 96 && m_currentWeapon != WEAPON_KNIFE)
			{
				pev->button |= IN_DUCK;
				m_moveSpeed = -pev->maxspeed;
			}
		}

		if (UsesSniper())
		{
			m_fightStyle = 1;
			m_lastFightStyleCheck = engine->GetTime();
		}
		else if (UsesRifle() || UsesSubmachineGun())
		{
			if (m_lastFightStyleCheck + 3.0f < engine->GetTime())
			{
				int rand = engine->RandomInt(1, 100);

				if (distance < 450)
					m_fightStyle = 0;
				else if (distance < 1024)
				{
					if (rand < (UsesSubmachineGun() ? 50 : 30))
						m_fightStyle = 0;
					else
						m_fightStyle = 1;
				}
				else
				{
					if (rand < (UsesSubmachineGun() ? 80 : 93))
						m_fightStyle = 1;
					else
						m_fightStyle = 0;
				}
				m_lastFightStyleCheck = engine->GetTime();
			}
		}
		else
		{
			if (m_lastFightStyleCheck + 3.0f < engine->GetTime())
			{
				if (engine->RandomInt(0, 100) < 65)
					m_fightStyle = 1;
				else
					m_fightStyle = 0;

				m_lastFightStyleCheck = engine->GetTime();
			}
		}

		if (((pev->button & IN_RELOAD) || (m_isReloading) || (m_skill >= 70 && m_fightStyle && distance < 800.0f)) &&
			GetGameMod () != 2 && GetGameMod () != 4)
		{
			if (m_strafeSetTime < engine->GetTime())
			{
				// to start strafing, we have to first figure out if the target is on the left side or right side
				MakeVectors(m_enemy->v.v_angle);

				Vector dirToPoint = (pev->origin - GetEntityOrigin(m_enemy)).Normalize2D();
				Vector rightSide = g_pGlobals->v_right.Normalize2D();

				if ((dirToPoint | rightSide) < 0)
					m_combatStrafeDir = 1;
				else
					m_combatStrafeDir = 0;

				if (engine->RandomInt(1, 100) < 30)
					m_combatStrafeDir ^= 1;

				m_strafeSetTime = engine->GetTime() + engine->RandomFloat(0.5, 2.5);
			}

			if (m_combatStrafeDir == 0)
			{
				if (!CheckWallOnLeft())
					m_strafeSpeed = -160.0f;
				else
				{
					m_combatStrafeDir ^= 1;
					m_strafeSetTime = engine->GetTime() + 0.7f;
				}
			}
			else
			{
				if (!CheckWallOnRight())
					m_strafeSpeed = 160.0f;
				else
				{
					m_combatStrafeDir ^= 1;
					m_strafeSetTime = engine->GetTime() + 1.0f;
				}
			}

			if (m_skill > 80 && (m_jumpTime + 5.0f < engine->GetTime() && IsOnFloor() && engine->RandomInt(0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.GetLength2D() > 150.0f))
				pev->button |= IN_JUMP;
		}
		else if ((GetGameMod() != 2 && m_fightStyle) || (m_fightStyle && m_moveSpeed == 0.0f))
		{
			bool shouldDuck = true; // should duck

			// check the enemy height
			float enemyHalfHeight = ((m_enemy->v.flags & FL_DUCKING) == FL_DUCKING ? 36.0f : 72.0f) / 2;

			// check center/feet
			if (!IsVisible(GetEntityOrigin(m_enemy), GetEntity()) && !IsVisible(GetEntityOrigin(m_enemy) + Vector(0, 0, -enemyHalfHeight), GetEntity()))
				shouldDuck = false;

			int nearestToEnemyPoint = g_waypoint->FindNearest(GetEntityOrigin(m_enemy));

			if (shouldDuck && GetCurrentTask()->taskID != TASK_SEEKCOVER && GetCurrentTask()->taskID != TASK_HUNTENEMY && (m_visibility & VISIBILITY_BODY) && !(m_visibility & VISIBILITY_OTHER) && g_waypoint->IsDuckVisible(m_currentWaypointIndex, nearestToEnemyPoint))
				m_duckTime = engine->GetTime() + m_frameInterval * 3.5f;

			m_moveSpeed = 0.0f;
			m_strafeSpeed = 0.0f;
			m_navTimeset = engine->GetTime();
		}
		else
			m_strafeSpeed = 0.0f;
	}

	if (m_duckTime > engine->GetTime())
	{
		m_moveSpeed = 0.0f;
		m_strafeSpeed = 0.0f;
	}

	if (GetGameMod() == 2)
		return;

	if (m_moveSpeed != 0.0f)
		m_moveSpeed = GetWalkSpeed();

	if (m_isReloading)
	{
		m_moveSpeed = -pev->maxspeed;
		m_duckTime = engine->GetTime() - (m_frameInterval * 4.0f);
	}

	if (!IsInWater() && !IsOnLadder())
	{
		if (m_moveSpeed != 0 || m_strafeSpeed != 0)
		{
			if (IsDeadlyDrop(pev->origin + (g_pGlobals->v_forward * m_moveSpeed * 0.2f) + (g_pGlobals->v_right * m_strafeSpeed * 0.2f) + (pev->velocity * m_frameInterval)))
			{
				m_strafeSpeed = -m_strafeSpeed;
				m_moveSpeed = -m_moveSpeed;

				pev->button &= ~IN_JUMP;
			}
		}
	}
}