Example #1
0
void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
{
	// get positions
	float Curvature = 0;
	float Speed = 0;
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		Curvature = m_pClient->m_Tuning.m_GrenadeCurvature;
		Speed = m_pClient->m_Tuning.m_GrenadeSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_SHOTGUN)
	{
		Curvature = m_pClient->m_Tuning.m_ShotgunCurvature;
		Speed = m_pClient->m_Tuning.m_ShotgunSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_GUN)
	{
		Curvature = m_pClient->m_Tuning.m_GunCurvature;
		Speed = m_pClient->m_Tuning.m_GunSpeed;
	}

	static float s_LastGameTickTime = Client()->GameTickTime();
	if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED))
		s_LastGameTickTime = Client()->GameTickTime();
	float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + s_LastGameTickTime;
	if(Ct < 0)
		return; // projectile havn't been shot yet

	vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
	vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
	vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
	vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);


	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
	Graphics()->QuadsBegin();

	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
	vec2 Vel = Pos-PrevPos;
	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick());


	// add particle for this projectile
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1);
		static float s_Time = 0.0f;
		static float s_LastLocalTime = Client()->LocalTime();

		if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
		{
			const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
			if(!pInfo->m_Paused)
				s_Time += (Client()->LocalTime()-s_LastLocalTime)*pInfo->m_Speed;
		}
		else
		{
			if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED))
				s_Time += Client()->LocalTime()-s_LastLocalTime;
		}

		Graphics()->QuadsSetRotation(s_Time*pi*2*2 + ItemID);
		s_LastLocalTime = Client()->LocalTime();
	}
	else
	{
		m_pClient->m_pEffects->BulletTrail(Pos);

		if(length(Vel) > 0.00001f)
			Graphics()->QuadsSetRotation(GetAngle(Vel));
		else
			Graphics()->QuadsSetRotation(0);

	}

	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32);
	Graphics()->QuadsDraw(&QuadItem, 1);
	Graphics()->QuadsSetRotation(0);
	Graphics()->QuadsEnd();
}
Example #2
0
void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
{

	// get positions
	float Curvature = 0;
	float Speed = 0;
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		Curvature = m_pClient->m_Tuning.m_GrenadeCurvature;
		Speed = m_pClient->m_Tuning.m_GrenadeSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_SHOTGUN)
	{
		Curvature = m_pClient->m_Tuning.m_ShotgunCurvature;
		Speed = m_pClient->m_Tuning.m_ShotgunSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_GUN)
	{
		Curvature = m_pClient->m_Tuning.m_GunCurvature;
		Speed = m_pClient->m_Tuning.m_GunSpeed;
	}

	float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
	if(Ct < 0)
		return; // projectile havn't been shot yet
		
	vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
	vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
	vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
	vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);


	// Draw shadows of grenades
	bool LocalPlayerInGame = m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_Team != -1;
	int explode = 0; // explode detecting
	
	if(g_Config.m_AntiPing && g_Config.m_AntiPingGrenade && g_Config.m_AntiPingOnlyIfBigLatency && (g_Config.m_AntiPingLatency <= m_pClient->m_Snap.m_pLocalInfo->m_Latency) && pCurrent->m_Type == WEAPON_GRENADE && LocalPlayerInGame && !m_pClient->m_Snap.m_pGameobj->m_GameOver)
	{
		Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
		Graphics()->QuadsBegin();
		
		// Calculate average prediction offset, because client_predtick() gets varial values :(((
		// Must be there is a normal way to realize it, but I'm too lazy to find it. 
		if (m_pClient->m_Average_Prediction_Offset == -1)
		{
			int Offset = Client()->PredGameTick() - Client()->GameTick();
			m_pClient->m_Prediction_Offset_Summ += Offset;
			m_pClient->m_Prediction_Offset_Count++;
			
			if (m_pClient->m_Prediction_Offset_Count >= 100)
			{
				m_pClient->m_Average_Prediction_Offset = round((float)m_pClient->m_Prediction_Offset_Summ / m_pClient->m_Prediction_Offset_Count);
			}
		}
		
		// Draw shadow only if grenade directed to local player (optionaly)
		int LocalCid = m_pClient->m_Snap.m_LocalClientID;
		CNetObj_CharacterCore& CurChar = m_pClient->m_Snap.m_aCharacters[LocalCid].m_Cur;
		CNetObj_CharacterCore& PrevChar = m_pClient->m_Snap.m_aCharacters[LocalCid].m_Prev;
		vec2 ServerPos = mix(vec2(PrevChar.m_X, PrevChar.m_Y), vec2(CurChar.m_X, CurChar.m_Y), Client()->IntraGameTick());
		
		bool GrenadeIsDirectedToLocalPlayer = true; 
		if (g_Config.m_AntiPingGrenadeSide)
		{
			float d1 = fabs(distance(Pos, ServerPos));
			float d2 = fabs(distance(PrevPos, ServerPos));
			bool GrenadeIsDirectedToLocalPlayer = d1 < d2;
		}
		
		// Detect explode
		int PredictedTick = Client()->PrevGameTick() + m_pClient->m_Average_Prediction_Offset;
		float PredictedCt = (PredictedTick - pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
		vec2 PredictedPos;
		vec2 PrevPredictedPos;
		
		if (g_Config.m_AntiPingGrenadeExpl)
		{
			// grenade explode on collisions
			float eps=g_Config.m_AntiPingGrenadeEps*0.0001f;
			for (int i=0; (Ct+i*eps<PredictedCt)&&!explode; i++)
			{
				PredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct+i*eps);
				PrevPredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed,  Ct+(i-1)*eps);
				if (Collision()->IntersectLine(PrevPredictedPos, PredictedPos, &PredictedPos, 0))
					explode=1;
			}
			
			// grenade explode if TimeSpan>GrenadeLifetime
			if (((PredictedTick-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED)>m_pClient->m_Tuning.m_GrenadeLifetime)
				explode=2;
				
			// Render explode
			if (explode==1)
			{
				m_pClient->m_pEffects->FakeExplosion(PredictedPos);
			}
			else if (explode==2)
			{
				float ExplodeCt=m_pClient->m_Tuning.m_GrenadeLifetime;
				PredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed, ExplodeCt);
				m_pClient->m_pEffects->FakeExplosion(PredictedPos);
			}
		}
		
		if (m_pClient->m_Average_Prediction_Offset != -1 && GrenadeIsDirectedToLocalPlayer && !explode && PredictedCt >= 0)
		{
			PredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed, PredictedCt);
			PrevPredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed, PredictedCt-0.001f);
			int shadow_type = pCurrent->m_Type; 
			Graphics()->SetColor(0, 1, 0, 0.75f); 
			RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(shadow_type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
			IGraphics::CQuadItem QuadItem(PredictedPos.x, PredictedPos.y, 28, 28);
			Graphics()->QuadsDraw(&QuadItem, 1);
		}
		
		Graphics()->QuadsSetRotation(0);
		Graphics()->QuadsEnd();
	}
	
	if (!(g_Config.m_AntiPingShowGrenadeIfExplode || explode==0 || pCurrent->m_Type != WEAPON_GRENADE))
		return;
	
	// draw original particle
	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
	Graphics()->QuadsBegin();
	
	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
	vec2 Vel = Pos-PrevPos;
	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick());
	

	// add particle for this projectile
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);
		
		if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
		{
			const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
			static float Time = 0;
			static float LastLocalTime = Client()->LocalTime();
		
			if(!pInfo->m_Paused)
				Time += (Client()->LocalTime()-LastLocalTime)*pInfo->m_Speed;
			
			Graphics()->QuadsSetRotation(Time*pi*2*2 + ItemID);
			
			LastLocalTime = Client()->LocalTime();
		}
		else
			Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemID);
	}
	else
	{
		if(pCurrent->m_Type != WEAPON_SHOTGUN)
			m_pClient->m_pEffects->SgBulletTrail(Pos);
		else
			m_pClient->m_pEffects->BulletTrail(Pos);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);

		if(length(Vel) > 0.00001f)
			Graphics()->QuadsSetRotation(GetAngle(Vel));
		else
			Graphics()->QuadsSetRotation(0);

	}

	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32);
	Graphics()->QuadsDraw(&QuadItem, 1);
	Graphics()->QuadsSetRotation(0);
	Graphics()->QuadsEnd();
}
Example #3
0
void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemId)
{

	// get positions
	float Curvature = 0;
	float Speed = 0;
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		Curvature = m_pClient->m_Tuning.m_GrenadeCurvature;
		Speed = m_pClient->m_Tuning.m_GrenadeSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_SHOTGUN)
	{
		Curvature = m_pClient->m_Tuning.m_ShotgunCurvature;
		Speed = m_pClient->m_Tuning.m_ShotgunSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_GUN)
	{
		Curvature = m_pClient->m_Tuning.m_GunCurvature;
		Speed = m_pClient->m_Tuning.m_GunSpeed;
	}

	float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
	if(Ct < 0)
		return; // projectile havn't been shot yet
		
	vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
	vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
	vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
	vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);


	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
	Graphics()->QuadsBegin();
	
	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
	vec2 Vel = Pos-PrevPos;
	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick());
	

	// add particle for this projectile
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);
		Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemId);
	}
	else
	{
		m_pClient->m_pEffects->BulletTrail(Pos);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);

		if(length(Vel) > 0.00001f)
			Graphics()->QuadsSetRotation(GetAngle(Vel));
		else
			Graphics()->QuadsSetRotation(0);

	}

	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32);
	Graphics()->QuadsDraw(&QuadItem, 1);
	Graphics()->QuadsSetRotation(0);
	Graphics()->QuadsEnd();
}
Example #4
0
void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
{

	// get positions
	float Curvature = 0;
	float Speed = 0;
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		Curvature = m_pClient->m_Tuning.m_GrenadeCurvature;
		Speed = m_pClient->m_Tuning.m_GrenadeSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_SHOTGUN)
	{
		Curvature = m_pClient->m_Tuning.m_ShotgunCurvature;
		Speed = m_pClient->m_Tuning.m_ShotgunSpeed;
	}
	else if(pCurrent->m_Type == WEAPON_GUN)
	{
		Curvature = m_pClient->m_Tuning.m_GunCurvature;
		Speed = m_pClient->m_Tuning.m_GunSpeed;
	}

	float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
	if(Ct < 0)
		return; // projectile havn't been shot yet
		
	vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
	vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
	vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
	vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);


	Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
	Graphics()->QuadsBegin();
	
	RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
	vec2 Vel = Pos-PrevPos;
	//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick());
	

	// add particle for this projectile
	if(pCurrent->m_Type == WEAPON_GRENADE)
	{
		m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);
		
		if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
		{
			const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
			static float Time = 0;
			static float LastLocalTime = Client()->LocalTime();
		
			if(!pInfo->m_Paused)
				Time += (Client()->LocalTime()-LastLocalTime)*pInfo->m_Speed;
			
			Graphics()->QuadsSetRotation(Time*pi*2*2 + ItemID);
			
			LastLocalTime = Client()->LocalTime();
		}
		else
			Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemID);
	}
	else
	{
		m_pClient->m_pEffects->BulletTrail(Pos);
		m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f);

		if(length(Vel) > 0.00001f)
			Graphics()->QuadsSetRotation(GetAngle(Vel));
		else
			Graphics()->QuadsSetRotation(0);

	}

	IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32);
	Graphics()->QuadsDraw(&QuadItem, 1);

	//--- Antiping
	// Draw shadows of grenades
	bool LocalPlayerInGame = 
		m_pClient->m_aClients[m_pClient->m_Snap.m_LocalCid].m_Team != -1;

	if(g_Config.m_AntiPing && pCurrent->m_Type == WEAPON_GRENADE && LocalPlayerInGame)
	{
		// Calculate average prediction offset, because client_predtick() gets varial values :(((
		// Must be there is a normal way to realize it, but I'm too lazy to find it. ^)
		if (m_pClient->m_Average_Prediction_Offset == -1)
		{
			int Offset = Client()->PredGameTick() - Client()->GameTick();
			m_pClient->m_Prediction_Offset_Summ += Offset;
			m_pClient->m_Prediction_Offset_Count++;

			if (m_pClient->m_Prediction_Offset_Count >= 100)
			{
				m_pClient->m_Average_Prediction_Offset = 
					round((float)m_pClient->m_Prediction_Offset_Summ / m_pClient->m_Prediction_Offset_Count);
			}
		}		

		// Draw shadow only if grenade directed to local player
		CNetObj_CharacterCore& CurChar = m_pClient->m_Snap.m_aCharacters[m_pClient->m_Snap.m_LocalCid].m_Cur;
		CNetObj_CharacterCore& PrevChar = m_pClient->m_Snap.m_aCharacters[m_pClient->m_Snap.m_LocalCid].m_Prev;
		vec2 ServerPos = mix(vec2(PrevChar.m_X, PrevChar.m_Y), vec2(CurChar.m_X, CurChar.m_Y), Client()->IntraGameTick());

		float d1 = distance(Pos, ServerPos);
		float d2 = distance(PrevPos, ServerPos);
		if (d1 < 0) d1 *= -1;
		if (d2 < 0) d2 *= -1;
		bool GrenadeIsDirectedToLocalPlayer = d1 < d2;

		if (m_pClient->m_Average_Prediction_Offset != -1 && GrenadeIsDirectedToLocalPlayer)
		{
			int PredictedTick = Client()->PrevGameTick() + m_pClient->m_Average_Prediction_Offset;
			float PredictedCt = (PredictedTick - pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime();
		
			if (PredictedCt >= 0)
			{
				int shadow_type = WEAPON_GUN; // Pistol bullet sprite is used for marker of shadow. TODO: use something custom.
				RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(shadow_type, 0, NUM_WEAPONS-1)].m_pSpriteProj);
				
				vec2 PredictedPos = CalcPos(StartPos, StartVel, Curvature, Speed, PredictedCt);
				
				IGraphics::CQuadItem QuadItem(PredictedPos.x, PredictedPos.y, 32, 32);
				Graphics()->QuadsDraw(&QuadItem, 1);
			}
		}
	}
	//---

	Graphics()->QuadsSetRotation(0);
	Graphics()->QuadsEnd();
}