Thinking: Difference between revisions
Thunder4ik (talk | contribs) m (→top: Unicodifying, replaced: [[Image: → [[File:) |
(Eu traduzi tudo, mas pode ter alguns erros... eu nao sou muito bom em ver ce tem) |
||
Line 2: | Line 2: | ||
[[File:Entity init.png|right|130px|The Source engine entity initialization process.]] | [[File:Entity init.png|right|130px|The Source engine entity initialization process.]] | ||
'''Think functions''' | '''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 | ||
{{clr}} | {{clr}} | ||
== | == Preparando == | ||
<code>SetNextThink()</code> | <code>SetNextThink()</code> é usado para poder configurar quando a entidade deve executar a próxima função ''think'' . O código aceita valores com virgula. | ||
<source lang=cpp> | <source lang=cpp> | ||
Line 11: | Line 11: | ||
{ | { | ||
BaseClass::Spawn(); | BaseClass::Spawn(); | ||
SetNextThink( gpGlobals->curtime ); // | SetNextThink( gpGlobals->curtime ); // Faça o think agora | ||
} | } | ||
void CMyEntity::Think() | void CMyEntity::Think() | ||
{ | { | ||
BaseClass::Think(); // | BaseClass::Think(); //Sempre faça isso se você substituir Think()! | ||
Msg( " | Msg( "Penso ,logo existo.\n" ); | ||
SetNextThink( gpGlobals->curtime + 1 ); // | SetNextThink( gpGlobals->curtime + 1 ); // Execute o '' think'' depois de 1 segundo! | ||
} | } | ||
</source> | </source> | ||
Olhe o uso de <tt>gpGlobals->curtime</tt> para fazer com que o valor passado seja relativo ao tempo de execução. | |||
{{tip|<code>SetNextThink(-1)</code> | {{tip|<code>SetNextThink(-1)</code> ira cancelar qualquer '' think ''futuro! . É melhor usar esse comparado ao<tt>SetNextThink(NULL)</tt>, pois o<tt>TICK_NEVER_THINK</tt> é -1.}} | ||
== | == Novas Think Functions == | ||
Uma entidade pode ter inúmeras ''think functions'' adicionas. Para fazer uma nova: | |||
# | # Tenha certeza que a função é do tipo<tt>void</tt>. | ||
# | # Adicione ela para a [[DATADESC]] da entidade, usando <tt>DEFINE_THINKFUNC()</tt>!. | ||
# | # Chame <code>SetThink()</code> e passe o pointer para a função! (olhe o exemplo abaixo). | ||
# | # Tenha certeza que <code>DECLARE_DATADESC();</code> esta em sua classe! | ||
<source lang=cpp> | <source lang=cpp> | ||
BEGIN_DATADESC( CMyEntity ) | BEGIN_DATADESC( CMyEntity ) | ||
DEFINE_THINKFUNC( MyThink ), // | DEFINE_THINKFUNC( MyThink ), // Registre uma nova função | ||
END_DATADESC() | END_DATADESC() | ||
Line 41: | Line 41: | ||
{ | { | ||
BaseClass::Spawn(); | BaseClass::Spawn(); | ||
SetThink( &CMyEntity::MyThink ); // | SetThink( &CMyEntity::MyThink ); // Passe o pointer da função | ||
SetNextThink(gpGlobals->curtime); | SetNextThink(gpGlobals->curtime); | ||
} | } | ||
Line 47: | Line 47: | ||
void CMyEntity::MyThink() | void CMyEntity::MyThink() | ||
{ | { | ||
Msg( " | Msg( "Penso,logo existo.\n" ); | ||
SetNextThink( gpGlobals->curtime + 1 ); | SetNextThink( gpGlobals->curtime + 1 ); | ||
} | } | ||
</source> | </source> | ||
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|<code>SetThink()</code> | {{tip|<code>SetThink()</code> 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: | |||
# | # Chame <code>RegisterThinkContext([[string]] NomeDoContexto)</code> | ||
# | # Use< code>SetContextThink([[void]]* Function, float NextThinkTime, string NomeDoContexto)</code> | ||
# For subsequent thinks, call <code>SetNextThink(float NextThinkTime, string | # For subsequent thinks, call <code>SetNextThink(float NextThinkTime, string NomeDoContexto)</code> | ||
<source lang=cpp> | <source lang=cpp> | ||
Line 68: | Line 68: | ||
void CMyEntity::Spawn() | void CMyEntity::Spawn() | ||
{ | { | ||
SetNextThink( gpGlobals->curtime ); // | SetNextThink( gpGlobals->curtime ); //Loop de pensamento padrão - sem contexto | ||
RegisterThinkContext( "TestContext" ); | RegisterThinkContext( "TestContext" ); | ||
SetContextThink( &CMyEntity::ContextThink, gpGlobals->curtime, " | SetContextThink( &CMyEntity::ContextThink, gpGlobals->curtime, "ContextoTest" ); | ||
} | } | ||
Line 89: | Line 89: | ||
</source> | </source> | ||
Isso cria dois loops de pensamento simultâneos, ambos gravando no console em taxas diferentes. | |||
{{tip| | {{tip|Criar um novo contexto é uma ótima maneira de atrasar chamadas de função para o futuro sem perturbar os ciclos de pensamento existentes.}} | ||
== Utilidades == | |||
<source lang=cpp> | <source lang=cpp> | ||
float GetLastThink() | float GetLastThink() // Pegamos o ultimo ''think'' que foi executado | ||
float GetNextThink() | float GetNextThink() // Pegamos o proximo ''think'' a ser executado | ||
int GetLastThinkTick() | int GetLastThinkTick() //Pegamos o ultimo ''tick'' do ultimo ''think'' que foi executado | ||
int GetNextThinkTick() | int GetNextThinkTick() // Pegamos o proximo ''tick'' do próximo ''think'' a ser executado | ||
</source> | </source> | ||
[[File:Barnacle.jpg|right|50px|link=npc_barnacle]] | [[File:Barnacle.jpg|right|50px|link=npc_barnacle]] | ||
As funções <code>GetLast</code> são úteis para controlar a taxa com que algo ocorre. | |||
Este código de pensamento de {{ent|npc_barnacle}} modula a velocidade do movimento da língua, mesmo que a frequência do pensamento mude: | |||
<source lang=cpp> | |||
float dt = gpGlobals->curtime - GetLastThink(); // dt é "delta time" | |||
float dt = gpGlobals->curtime - GetLastThink(); // dt | SetAltitude( m_flAltitude + m_flBarnaclePullSpeed * dt ); // Mudamos a altitude de sua língua! | ||
SetAltitude( m_flAltitude + m_flBarnaclePullSpeed * dt ); // | |||
</source> | </source> | ||
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. | |||
==<tt>ClientThink()</tt>== | ==<tt>ClientThink()</tt>== | ||
Thinking | ''Thinking'' também pode acontecer no cliente, mas os efeitos são limitados!. Apenas podemos usar 1 função para cada entidade. | ||
<span style="color:blue;">void</span> C_MyEntity::ClientThink() | <span style="color:blue;">void</span> C_MyEntity::ClientThink() | ||
{ | { | ||
Msg( <span style="color:brown;">" | Msg( <span style="color:brown;">"NÃO COLOQUE NADA [[PESADO]] NESSAFUNÇÃO!\n"</span> ); | ||
SetNextClientThink( CLIENT_THINK_ALWAYS ); <span style="color:green;">/ | SetNextClientThink( CLIENT_THINK_ALWAYS ); <span style="color:green;">/ ''Think'' é executado todo frame</span> | ||
} | } | ||
Alguns exemplos de ''client-side'' thinking são: | |||
* | * Efeitos visuais/partículas | ||
* VGUI | * 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) | ||
<code>SetNextClientThink()</code> | <code>SetNextClientThink()</code> é usado para agendar <code>ClientThink()</code>. Existem dois valores especiais que ele aceita: | ||
; <tt>CLIENT_THINK_ALWAYS</tt>: | ; <tt>CLIENT_THINK_ALWAYS</tt>: Pense no cliente uma vez a cada frame. Use com cuidado! {{tip|Use <code>gpGlobals->frametime</code> para regular a velocidade.}} | ||
; <tt>CLIENT_THINK_NEVER</tt>: | ; <tt>CLIENT_THINK_NEVER</tt>: pause todo o pensamento automatizado do cliente. |
Revision as of 08:21, 16 January 2024
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.

SetNextThink(-1)
ira cancelar qualquer think futuro! . É melhor usar esse comparado aoSetNextThink(NULL), pois oTICK_NEVER_THINK é -1.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 DATADESC 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!

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:
- Chame
RegisterThinkContext(string NomeDoContexto)
- Use< code>SetContextThink(void* Function, float NextThinkTime, string NomeDoContexto)
- 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 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:Use
gpGlobals->frametime
para regular a velocidade. - CLIENT_THINK_NEVER
- pause todo o pensamento automatizado do cliente.