Pt-br/Thinking

Category:AICategory:FunctionsCategory:Programming
Think functions permitem entidades preparar código para ser feito no futuro. Quando você reagendar os Thinks, loops automáticos podem ser criados para fazer a entidade fazer as funções automaticamente
== Preparando ==
SetNextThink() é usado para poder configurar quando a entidade deve executar a próxima função think . O código aceita valores com virgula.
void CMyEntity::Spawn()
{
	BaseClass::Spawn();
	SetNextThink( gpGlobals->curtime ); // Faça o think agora
}
void CMyEntity::Think()
{
	BaseClass::Think(); //Sempre faça isso se você substituir Think()!
	Msg( "Penso ,logo existo.\n" );
	SetNextThink( gpGlobals->curtime + 1 ); // Execute o think depois de 1 segundo!
}
Olhe o uso de gpGlobals->curtime para fazer com que o valor passado seja relativo ao tempo de execução.
== Novas Think Functions ==
Uma entidade pode ter inúmeras think functions adicionas. Para fazer uma nova:
# Tenha certeza que a função é do tipovoid.
# Adicione ela para a da entidade, usando DEFINE_THINKFUNC()!.
# Chame SetThink() e passe o pointer para a função! (olhe o exemplo abaixo).
# Tenha certeza que DECLARE_DATADESC(); esta em sua classe!
BEGIN_DATADESC( CMyEntity )
	DEFINE_THINKFUNC( MyThink ), // Registre uma nova função 
END_DATADESC()
void CMyEntity::Spawn()
{
	BaseClass::Spawn();
	SetThink( &CMyEntity::MyThink ); // Passe o pointer da função
	SetNextThink(gpGlobals->curtime);
}
void CMyEntity::MyThink()
{
	Msg( "Penso,logo existo.\n" );
	SetNextThink( gpGlobals->curtime + 1 );
}
Devindo seu codigos entre outras funções que estão sendo usado para o think deixa mais fácil trocar entre modos de operação!
== Usando contexto ==
É possível agendar qualquer número de funções de pensamento lado a lado com "contextos de thinks". Para criar um novo contexto:
# Chame RegisterThinkContext( NomeDoContexto)
# Use< code>SetContextThink(* Function, float NextThinkTime, string NomeDoContexto)</code>
# For subsequent thinks, call SetNextThink(float NextThinkTime, string NomeDoContexto)
BEGIN_DATADESC( CMyEntity )
	DEFINE_THINKFUNC( ContextThink ),
END_DATADESC()
void CMyEntity::Spawn()
{
	SetNextThink( gpGlobals->curtime ); //Loop de pensamento padrão - sem contexto
	
	RegisterThinkContext( "TestContext" );
	SetContextThink( &CMyEntity::ContextThink, gpGlobals->curtime, "ContextoTest" );
}
void CMyEntity::Think()
{
	BaseClass::Think();
	Msg( "Think\n" );
	SetNextThink( gpGlobals->curtime + .1 );
}
void CMyEntity::ContextThink()
{
	Msg( "Context think\n" );
	SetNextThink(gpGlobals->curtime + .2, "TestContext" );
}
Isso cria dois loops de pensamento simultâneos, ambos gravando no console em taxas diferentes.
== Utilidades ==
float	GetLastThink() // Pegamos o ultimo think que foi executado
float	GetNextThink() // Pegamos o proximo think a ser executado
int	GetLastThinkTick() //Pegamos o ultimo tick do ultimo think que foi executado
int	GetNextThinkTick() // Pegamos o proximo tick do próximo think a ser executado
As funções GetLast são úteis para controlar a taxa com que algo ocorre.
Este código de pensamento de modula a velocidade do movimento da língua, mesmo que a frequência do pensamento mude:
float dt = gpGlobals->curtime - GetLastThink(); // dt é "delta time"
SetAltitude( m_flAltitude + m_flBarnaclePullSpeed * dt ); // Mudamos a altitude de sua língua!
Para que sua animação não seja suave, esse código precisaria ser executado a cada quadro. Isso é exatamente o que acontece, até que a craca não esteja mais no do jogador e a taxa diminua - exigindo assim o código acima.
==ClientThink()==
Thinking também pode acontecer no cliente, mas os efeitos são limitados!. Apenas podemos usar 1 função para cada entidade.
 void C_MyEntity::ClientThink()
 {
 	Msg( "NÃO COLOQUE NADA NESSAFUNÇÃO!\n" );
 	SetNextClientThink( CLIENT_THINK_ALWAYS ); / Think é executado todo frame
 }
Alguns exemplos de client-side thinking são:
* Efeitos visuais/partículas
* Interação com VGUI
* Modificação da velocidade do jogador (feita tanto no cliente quanto no servidor para evitar erros de )
* Pernas dos Peregrinos quebrando cordas (desativado por padrão)
SetNextClientThink() é usado para agendar ClientThink(). Existem dois valores especiais que ele aceita:
; CLIENT_THINK_ALWAYS: Pense no cliente uma vez a cada frame. Use com cuidado! 
; CLIENT_THINK_NEVER: pause todo o pensamento automatizado do cliente.