Moderator elections are being held. See Valve Developer Community:Moderator elections for more details.
Users who would like to run for moderator must be autoconfirmed and have at least 100 edits. Users can check their own edit count at Special:Preferences.

Think

From Valve Developer Community
Jump to: navigation, search
English (en)Deutsch (de)Español (es)Português do Brasil (pt-br)Русский (ru)中文 (zh)
... Icon-Important.png
Como a source engine inicia uma entidade!

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.

Tip.pngTip:SetNextThink(-1) ira cancelar qualquer think futuro! . É melhor usar esse comparado ao SetNextThink(NULL), pois o TICK_NEVER_THINK é -1.

Novas Think Functions

Uma entidade pode ter inúmeras think functions adicionas. Para fazer uma nova:

  1. Tenha certeza que a função é do tipovoid.
  2. Adicione ela para a DATADESC da entidade, usando DEFINE_THINKFUNC()!.
  3. Chame SetThink() e passe o pointer para a função! (olhe o exemplo abaixo).
  4. 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!

Tip.pngTip:SetThink() pode ser chamado dentro de uma função think também. A próxima chamado será na nova funçã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:

  1. Chame RegisterThinkContext(string NomeDoContexto)
  2. Use< code>SetContextThink(void* Function, float NextThinkTime, string NomeDoContexto)
  3. 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.

Tip.pngTip:Criar um novo contexto é uma ótima maneira de atrasar chamadas de função para o futuro sem perturbar os ciclos de pensamento existentes.

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
Barnacle.jpg

As funções GetLast são úteis para controlar a taxa com que algo ocorre. Este código de pensamento de npc_barnacle 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 esquelética 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 PVS 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 PESADO 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 predição)
  • 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!
Tip.pngTip:Use gpGlobals->frametime para regular a velocidade.
CLIENT_THINK_NEVER
pause todo o pensamento automatizado do cliente.