Compartilhe
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 09:23
Concluindo esta parte você vai:
Saber responder o que é, como usar e quais as vantagens do uso do GOSUB e CLEO_CALL em seu script.
Também terá dicas ao longo do tutorial, na qual te ajudará a pensar melhor sobre a organização dos seus scripts.


Nada precisa ser repetitivo

Você já deve estar começando a criar alguns scripts simples, e já pode começar a imaginar melhores métodos para se fazer a mesma coisa.
Em programação (assim como várias outras áreas!) pode ser feita de incontáveis maneiras diferentes dependente do raciocínio da pessoa, assim como há formas "boas" e "ruins" de fazer algumas coisas.

Uma das coisas ruins, é a alta repetição da mesma coisa, o que poderia ser feita somente uma vez e chamada várias vezes! Ou simplesmente a mudança de posição de um código, para facilitar a leitura.


GOSUB - Sub tarefa


O comando "GOSUB" ("go sub", leia isso como "ir para uma sub-tarefa") é usado para ir para uma "tarefa secundária", e voltar de onde veio!

É muito parecido com o GOTO, a única diferença é que nós temos o comando "RETURN" onde faz voltar de onde saiu:


Sim, isso é extremamente simples e o tutorial já até poderia acabar por aqui...

Vamos imaginar que você ainda não entendeu. Bem, você já sabe muito bem como o GOTO funciona, né?
Então veja isso:

É a mesma coisa! Mas vamos ser sinceros, ficou confuso e feio, né? o GOSUB é muito mais elegante.

E como sempre, sinta-se livre! Você pode fazer um dentro do outro:

O limite é de 8 GOSUBs ao mesmo tempo. Parece pequeno, mas, sério, eu gosto de GOSUB e uso demais nos meus mods, e em toda a minha vida eu nunca sofri este limite. Acredito que você sofrerá só caso usar ele exageradamente.

No exemplo acima, ao segurar a tecla "Y" irá chamar um GOSUB que aparece "Oi!" e checa se apertou a tecla H. Se apertou, entra em um segundo GOSUB para mostrar a mensagem "Simples." e volta. Quando voltar, o script voltará de onde este segundo GOSUB saiu (ali na linha 15!!!) e continuar o seu caminho. Até encontrar o outro RETURN (ali na linha 17), e voltar lá no início: Na linha 8.

É sim muito simples de entender, é só um vai e volta. E no exemplo que eu falei acima foi: Vai, vai, volta, volta. Entendeu?

Depois de ter certeza de ter entendido o que é GOSUB, você já terá facilidade de entender os princípios de um CLEO_CALL:


CLEO_CALL - Uma sub-tarefa mais avançada


Eu adoro CLEO_CALL!

Ele é igual um GOSUB — inicie sua mente com isso, pense num GOSUB! — mas a diferença é que o que acontece num CLEO_CALL, não influencia no que está fora dele.

Vamos devagar. Veja a comparação:

É A MESMA COISA.
"E aquele "0" ali?"
NÃO IMPORTA, ele nem é utilizado (antigamente ele era, você saberá o motivo). Simplesmente ignore o "0".

Tá, agora vamos para as diferenças:

Código copiável:
Spoiler:

Código:
SCRIPT_START
{
NOP

LVAR_INT var1
var1 = 12

main_loop:
WAIT 0
IF IS_KEY_PRESSED VK_KEY_Y
    GOSUB label
ENDIF
GOTO main_loop

label:
PRINT_FORMATTED_NOW "%d" 1000 var1
RETURN
}
SCRIPT_END
Isso irá mostrar na tela o valor da variável "var1" quando você apertar a tecla Y. Qual o valor? 12. Um número que você já deve gostar.

E se fazermos igual, mas com CLEO_CALL?

Código copiável:

Código:
SCRIPT_START
{
NOP

LVAR_INT var1
var1 = 12

main_loop:
WAIT 0
IF IS_KEY_PRESSED VK_KEY_Y
    CLEO_CALL label 0
ENDIF
GOTO main_loop

label:
PRINT_FORMATTED_NOW "%d" 1000 var1
CLEO_RETURN 0
}
SCRIPT_END
Vai aparecer "0" :)

"What?"

Entendeu? As variáveis existentes deixam de existir quando você chama um CLEO_CALL! Lá dentro não existe o que há lá fora.
Não importa que a "var1" seja "12" lá fora. Dentro do CLEO_CALL ela não existe! Ela tem o valor 0 (pois todas as variáveis, por padrão, têm o valor "0").

Mas calma, o importante está por vir: Nós podemos enviar a nossa "var1" para o CLEO_CALL!


Envio e retorno de valores


É agora que a coisa fica interessante!

Vamos virar de cabeça pra baixo:

Pela primeira vez aqui no tutorial você verá um script com o uso de 2 escopos.

Opcional: Vou começar a indentar (adicionar um TAB) dentro do escopo, para facilitar enxergar onde começa e termina eles. Você pode preferir fazer assim em seus scripts.

Opcional: Usarei os carácteres "(" ")" "," para deixar o código melhor para ler. Você ainda não deve saber, mas estes carácteres são tratados como espaço no compilador, ou seja, eles não influenciam em absolutamente nada no seu código, somente visualmente! Então eles têm certa utilidade, como separar variáveis para ficar melhor para ler:

Código copiável:

Código:
SCRIPT_START
{
    NOP

    LVAR_INT var1

    var1 = 12

    main_loop:
    WAIT 0
    CLEO_CALL label 0 (var1)(var1)
    PRINT_FORMATTED_NOW "%d" 1000 var1
    GOTO main_loop
}

{
    LVAR_INT in_var

    label:
    in_var = 13
    CLEO_RETURN 0 (in_var)
}

SCRIPT_END
Este script irá mostrar "13" na tela.
Está bem diferente. Preste bem a atenção.

Perceba o "(var1)(var1)"
O primeiro "(var1)" é a variável enviada para dentro do CLEO_CALL. Chegando lá, o valor desta variável entrará na primeira variável declarada lá dentro, neste caso, a variável "in_var" (é a única!). Ou seja, lá dentro do CLEO_CALL, a "in_var" terá o valor da "var1", que é 12.
Mas eu mudei o valor, e agora será "13".
No "CLEO_RETURN" eu retornei a variável "in_var".
Ao retornar, o valor dela irá para o segundo "(var1)", ou seja, o valor da "in_var" irá para a "var1" lá fora do CLEO_CALL.
Agora "var1" tem o valor "13".

O mesmo aconteceria se fosse assim, usando uma segunda variável:

Ou seja, eu enviei o valor da "var1", mas pedi para que quando retornasse, o novo valor caísse na "var2". Ou seja, a "var1" continuou 12, mas a "var2" agora tem o valor "13", pois eu retornei o valor nela, e não na "var1" como antes.

Você tem que entender que isso é muito dinâmico e você pode enviar e retornar quantas variáveis for necessário!

Dê uma olhada neste exemplo:

Sim, a variável "var1" terá agora o valor "13" e mostrará "13" na tela!
Tudo o que o script acima fez foi: Retornar o número "13" para a variável de retorno. E qual a variável de retorno? "var1"!

Agora eu criei uma função que: Pega uma variável, e um valor, e usa este valor para somar naquela variável, e retorna o valor dela:

Código copiável:

Código:
SCRIPT_START
{
    NOP

    LVAR_INT var1

    main_loop:
    WAIT 0
    CLEO_CALL add 0 (var1, 10)(var1)
    PRINT_FORMATTED_NOW "%d" 1000 var1
    GOTO main_loop
}

{
    LVAR_INT in_var
    LVAR_INT value

    add:
    in_var += value
    CLEO_RETURN 0 (in_var)
}

SCRIPT_END
O resultado vai ser a variável "var1" aumentando de 10 em 10 sem parar (lembre-se que estamos dentro de um loop!)

Dentro do CLEO_CALL, a "in_var" vai ter o valor atual da "var1" lá fora. Já a variável "value" vai ter o valor "10" (que é o valor que você enviou pra ela!).


Agora você está começando a entender a utilidade disso, né?

CLEO_CALL é muitíssimo útil para fazer operações mais complexas (ou repetitivas) onde você envia argumentos, e ele faz e/ou retorna alguma coisa para você.

Veja só este exemplo útil:

Código copiável:

Código:
SCRIPT_START
{
    NOP

    LVAR_INT scplayer
    LVAR_FLOAT x y z

    GET_PLAYER_CHAR 0 scplayer

    main_loop:
    WAIT 0
    IF IS_KEY_PRESSED VK_KEY_Y
        CLEO_CALL pegar_rua_proxima 0 (scplayer) (x y z)
        PRINT_FORMATTED_NOW "A coord da rua mais proxima eh: %.4f %.4f %.4f" 1000 (x y z)
        DRAW_CORONA (x y z) (1.0) (CORONATYPE_SHINYSTAR, FLARETYPE_NONE) (255 0 0)
    ENDIF
    GOTO main_loop
}

{
    LVAR_INT char // variável introduzida pelo CALL (neste caso em específico, a "scplayer")

    LVAR_FLOAT player_x player_y player_z
    LVAR_FLOAT rua_x rua_y rua_z

    pegar_rua_proxima:
    GET_CHAR_COORDINATES char (player_x player_y player_z)
    GET_CLOSEST_CAR_NODE (player_x player_y player_z) (rua_x rua_y rua_z)
    CLEO_RETURN 0 (rua_x rua_y rua_z)
}
SCRIPT_END
Este CLEO_CALL tem a função de: Pegar a coordenada de um char (você pode usar qualquer char, não precisa ser o CJ), e com ela, pegar a coordenada do node (path) de carros mais próximo. O valor retornado será a coordenada X Y Z daquele node (path).
Retornando, eu usei esta coordenada para mostrar o valor dela na tela, e criar uma luz (corona) vermelha lá.


Eu gosto de imaginar "CLEO_CALL" como "comandos personalizados". Sabe quando você quer um comando que não existe, mas é possível você mesmo fazer este comando? Então.

Inclusive, isso é facilmente compartilhável com as pessoas, e este é o principal motivo da categoria "Ferramentas e utilitários - Scripts" existir aqui no fórum: Lá você geralmente encontra CLEO_CALLs (antigamente chamados de "call_scm_func") úteis para o seu script. (até o presente momento só tem funções para o Sanny Builder lá, em breve será traduzido/convertido para o GTA3script).

Hoje mesmo fiz um CLEO_CALL que posso compartilhar aqui:
Código:
{
    LVAR_INT hChar // In
    LVAR_INT iTempVar
    GetCharPedStatsID:
    GET_PED_POINTER hChar iTempVar //CPed
    iTempVar += 0x59C //m_pStat
    READ_MEMORY iTempVar 4 FALSE iTempVar //CPedStats (+0x59C)
    READ_MEMORY iTempVar 4 FALSE iTempVar //nNum (+0x0)
    CLEO_RETURN 0 iTempVar
}
Simplesmente adicione isso em algum lugar do seu script (embaixo do seu } como os exemplos acima, ou até embaixo do SCRIPT_END, mas eu não gosto assim) e use a seguinte chamada:
Código:
CLEO_CALL GetCharPedStatsID 0 (hChar)(iPedStatsID)
A variável "iPedStatsID" terá o número ID do "ped stat" (do "data\pedstats.dat") da pessoa.

Veja este script completo que pega uma pessoa próxima, usa esta função para pegar o ped stat dela, e checa e mostra na tela uma mensagem caso seja um policial, da sua gangue, ou uma puta.
Código:
SCRIPT_START
{
    NOP

    LVAR_INT scplayer
    LVAR_INT char vehicle
    LVAR_INT iPedStatsNum

    CONST_INT STAT_PLAYER 0          
    CONST_INT STAT_COP 1          
    CONST_INT STAT_MEDIC 2        
    CONST_INT STAT_FIREMAN 3      
    CONST_INT STAT_GANG1 4        
    CONST_INT STAT_GANG2 5        
    CONST_INT STAT_GANG3 6        
    CONST_INT STAT_GANG4 7        
    CONST_INT STAT_GANG5 8        
    CONST_INT STAT_GANG6 9        
    CONST_INT STAT_GANG7 10        
    CONST_INT STAT_GANG8 11        
    CONST_INT STAT_GANG9 12        
    CONST_INT STAT_GANG10 13      
    CONST_INT STAT_STREET_GUY 14  
    CONST_INT STAT_SUIT_GUY 15    
    CONST_INT STAT_SENSIBLE_GUY 16
    CONST_INT STAT_GEEK_GUY 17    
    CONST_INT STAT_OLD_GUY 18      
    CONST_INT STAT_TOUGH_GUY 19    
    CONST_INT STAT_STREET_GIRL 20  
    CONST_INT STAT_SUIT_GIRL 21    
    CONST_INT STAT_SENSIBLE_GIRL 22
    CONST_INT STAT_GEEK_GIRL 23    
    CONST_INT STAT_OLD_GIRL 24    
    CONST_INT STAT_TOUGH_GIRL 25  
    CONST_INT STAT_TRAMP_MALE 26  
    CONST_INT STAT_TRAMP_FEMALE 27
    CONST_INT STAT_TOURIST 28      
    CONST_INT STAT_PROSTITUTE 29  
    CONST_INT STAT_CRIMINAL 30    
    CONST_INT STAT_BUSKER 31      
    CONST_INT STAT_TAXIDRIVER 32  
    CONST_INT STAT_PSYCHO 33      
    CONST_INT STAT_STEWARD 34      
    CONST_INT STAT_SPORTSFAN 35    
    CONST_INT STAT_SHOPPER 36      
    CONST_INT STAT_OLDSHOPPER 37  
    CONST_INT STAT_BEACH_GUY 38
    CONST_INT STAT_BEACH_GIRL 39
    CONST_INT STAT_SKATER 40
    CONST_INT STAT_STD_MISSION 41
    CONST_INT STAT_COWARD 42

    GET_PLAYER_CHAR 0 scplayer

    main_loop:
    WAIT 0
    STORE_CLOSEST_ENTITIES (scplayer) vehicle, char
    IF DOES_CHAR_EXIST char
        CLEO_CALL GetCharPedStatsID 0 (char)(iPedStatsNum)
        IF iPedStatsNum = STAT_PROSTITUTE
            PRINT_STRING_NOW "A pessoa proxima e uma puta!" 1000
        ENDIF
        IF iPedStatsNum = STAT_COP
            PRINT_STRING_NOW "A pessoa proxima e um policial!" 1000
        ENDIF
        IF iPedStatsNum = STAT_GANG2
            PRINT_STRING_NOW "A pessoa proxima e da sua gangue!" 1000
        ENDIF
    ENDIF
    GOTO main_loop
}

{
    LVAR_INT hChar // In
    LVAR_INT iTempVar
    GetCharPedStatsID:
    GET_PED_POINTER hChar iTempVar //CPed
    iTempVar += 0x59C //m_pStat
    READ_MEMORY iTempVar 4 FALSE iTempVar //CPedStats (+0x59C)
    READ_MEMORY iTempVar 4 FALSE iTempVar //nNum (+0x0)
    CLEO_RETURN 0 iTempVar
}
SCRIPT_END

Viu como é interessante e útil ter vários CLEO_CALL no seu script?


E sim, você também pode usar um CLEO_CALL dentro do outro, mas diferente do GOSUB, isso é infinito! (1024, para ser mais exato, o que é um número gigante). Ou seja, você pode fazer até umas táticas malucas de recursão que não terá problema.

Você SEMPRE tem que ficar atento para quantas variáveis você envia e/ou retorna, ou o compilador dará erros.

Você pode tratar um CLEO_CALL normalmente, usando WAIT etc, mas não é uma boa prática pois na maioria das vezes você só está chamando ele para fazer uma coisa e retornar outra, ele é útil para coisas instantâneas (a não ser que você esteja usando ele para realmente abrir novas portas para "novos" caminhos de script). Portanto, prefira usá-lo sem WAIT, a não ser que o que você realmente esteja fazendo uma coisa que precise de WAIT.

E sobre aquele "0" que nós nunca mexemos nele: Ele era usado na época do Sanny Builder, onde você ficava tendo de digitar o número de quantas variáveis (ou outros valores! Melhor dizendo: Quantos argumentos) você está enviando, ou retornando. Agora, no GTA3script esta contagem é automática, então tudo o que você tem que fazer é deixar "0" ali.


Deixando claro!


Para terminar, eu queria deixar claro que GOSUB e CLEO_CALL é sim muitíssimo utilizado em mods.
Por exemplo, eu tenho um MP3 player e foi apertado a tecla para ir para a próxima música: Eu usarei um GOSUB para descarregar a música atual, e outro GOSUB para chamar a próxima música. O script ficaria assim:
Código:
IF IS_KEY_PRESSED VK_KEY_K
    GOSUB DescarregarMusicaAtual
    GOSUB CarregarProximaMusica
    GOSUB Play
    WHILE IS_KEY_PRESSED VK_KEY_K
        WAIT 0
    ENDWHILE
ENDIF
E todo o procedimento de descarregar uma música e tocar outra, estaria lá nas labels dos GOSUBs, enquanto no script principal, eu teria isso acima, na qual deixa tudo muito mais confortável para ler, né?

Outro exemplo foi num mod meu chamado Ear Ringing (zumbido no ouvido) onde eu escolhi fazer o loop principal do mod funcionar totalmente por GOSUBs:

Note que a lógica do mod está aí, todo escrito por GOSUBs, de uma maneira muito fácil de ler e entender, enquanto o que cada GOSUB faz estão todos separados em outra parte do script, assim deixando mais limpo e não tirando o foco da parte principal do mod (o loop principal, onde está presente a lógica). Veja o código fonte completo. Acredito que o código deste mod ficou bem organizado.

É esta a dica que eu dou, tire os "códigos feios" da sua frente, jogue-os em algum canto e use um GOSUB para chamá-los, faça com que a parte principal do seu código seja limpa, assim também caprichando no nome das labels.

O CLEO_CALL também é ótimo para ser usado várias vezes, mas só use caso você realmente achar necessário "ir para fora" do script principal. Tanto que nos exemplos que eu fiz aqui são simples e óbvios, o único exemplo realmente útil foi o do ped stats, o resto podia ser feito direto no código, ou em algum GOSUB! Mas para o tutorial ficar mais fácil, usei exemplos fáceis mesmo.
É comum você no início não encontrar tanta utilidade em CLEO_CALL, por ser mais útil em coisas mais complexas.

Um dos exemplos "simples" e úteis para o CLEO_CALL, também seria você, por exemplo, está criando vários peds (CHARs), então quando você cria um CHAR você envia ele para um CLEO_CALL, onde neste CLEO_CALL teria comandos para "configurar" o seu CHAR.
Seria mais ou menos assim:
Código:
LVAR_INT char
ConfigurarChar:
SET_CHAR_HEALTH char 2000
SET_CHAR_WEAPON_SKILL char 2
SET_CHAR_MONEY char 1000
SET_CHAR_ACCURACY char 60
SET_CHAR_SHOOT_RATE char 80
CLEO_RETURN 0
E você criaria o CHAR, e chamaria a função acima desta maneira:
Código:
CREATE_CHAR PEDTYPE_GANG2 FAM1 0.0 0.0 0.0 membro1
CLEO_CALL ConfigurarChar 0 membro1
CREATE_CHAR PEDTYPE_GANG2 FAM1 0.0 0.0 0.0 membro2
CLEO_CALL ConfigurarChar 0 membro2
Viu como é divertido? É só liberar a sua mente.
Nota: Se ainda não viu, veja o tutorial de como criar CHARs etc.




Próxima parte:
14. Indentação


Última edição por Junior_Djjr em Seg 19 Jun 2017, 08:10, editado 4 vez(es) (Razão : Adicionado +1 exemplo de mod usando GOSUB)

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Básico
Scripter CLEO - Básico
Mensagens : 1022
Reputação : 82
Desde : 04/03/2013
Idade : 17
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:06
Ontem fiz uma função só porque não gosto de ficar colocando:
Código:
WHILE IS_KEY_PRESSED
 WAIT 0
ENDWHILE
Sempre que vou fazer uma checagem de tecla, então ficou assim:
Código:
{
    KeyPressed:
    LVAR_INT key

    IF IS_KEY_PRESSED key
        WHILE IS_KEY_PRESSED key
            WAIT 0
        ENDWHILE
        IS_PC_VERSION // makes flag be true
    ENDIF

    CLEO_RETURN 0
}
A checagem na parte principal do script então passaria a ser uma única linha para sempre que eu precisasse:
Código:
IF CLEO_CALL KeyPressed 0 (0x4C) // VK_KEY_L
 value += 0.1
ENDIF

Mas acho que a questão aqui nesse tutorial é "A custo do que?"
Óbvio que quando eu faço isso o código fica bem mais legível, só que diminui o desempenho dele já que foi necessário a adição de mais um IF na hora da chamada (IF CLEO_CALL), do CLEO_CALL em si que precisa fazer um jump para uma parte remota do código e do opcode que precisei utilizar a mais para mudar a flag (IS_PC_VERSION).

O que eu fiz aqui seria errado?

Na minha opinião, se você tiver que checar muitas teclas no script e ele for muito grande, vale a pena por questões de legibilidade.
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:10
Ohh, adição de +1 IF então fica pesado? Fica nada, uma checagenzinha é nada. Se cria mods de loops de 1000 linhas rodando a cada frame e mesmo assim não há perda de FPS Fuch That Guy

Eu prefiro não usar por causa de outro motivo: Só ativará após SOLTAR a tecla, o que não gosto, dá uma sensação de baixo desempenho (não responde no mesmo instante).

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Básico
Scripter CLEO - Básico
Mensagens : 1022
Reputação : 82
Desde : 04/03/2013
Idade : 17
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:21
@Junior_Djjr escreveu:Ohh, adição de +1 IF então fica pesado? Fica nada, uma checagenzinha é nada. Se cria mods de loops de 1000 linhas rodando a cada frame e mesmo assim não há perda de FPS Fuch That Guy
Com bastantes IF de resultados aleatórios tiraria bastante desempenho sim.
Concordo que não é bem o caso de um IS_KEY_PRESSED já que tem um padrão, na maioria das vezes o jogador não vai apertar as teclas.
Se tiver interesse nisso, leia aqui
(Link me ensinou isso ontem  :))

@Junior_Djjr escreveu:Eu prefiro não usar por causa de outro motivo: Só ativará após SOLTAR a tecla, o que não gosto, dá uma sensação de baixo desempenho (não responde no mesmo instante).
Isso é bem chato mesmo argh
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Bicho Piruleta
Mensagens : 671
Reputação : 111
Desde : 22/09/2015
Idade : 19
Localização : Salvador - BA
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:21
No tutorial só faltou o exemplo "o que se faz em Las Vegas, fica em Las Vegas", nunca vou esquecer isso Fuch That Guy, foi assim que aprendi scm_func.
Logo quando comecei a usar, colocava o nome das labels "Las_Vegas".
denilson gostoso

______________________________
" Everyone gonna remember my name ! "
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:24
@israel escreveu:No tutorial só faltou o exemplo "o que se faz em Las Vegas, fica em Las Vegas", nunca vou esquecer isso Fuch That Guy, foi assim que aprendi scm_func.
Logo quando comecei a usar, colocava o nome das labels "Las_Vegas".
denilson gostoso
Nossa, eu tinha colocado uma frase com essa referência, mas apaguei metade do tutorial pra reescrever e esqueci de re-colocar Fuch That Guy

edit: Acho que essa frase daria a entender que: As variáveis ficam armazenadas dentro do CLEO_CALL para sempre, e se você chamar ele de novo, elas estarão lá philosoraptor o que não é verdade.

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Bicho Piruleta
Mensagens : 671
Reputação : 111
Desde : 22/09/2015
Idade : 19
Localização : Salvador - BA
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:32
Raisins Face
O que se faz em Las Vegas, fica em Las Vegas até você sair de lá. serious?
Sei lá, no tutorial de scm_func deu pra entender.

______________________________
" Everyone gonna remember my name ! "
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:42
Ah, outra coisa ruim do método do Nex':
Não há como usar IF AND/OR junto com essa função, pois tem um IF interno, daí aquele IF irá "atrapalhar" o AND/OR. É mais outra coisa que quero abordar num segundo tutorial de condições.

E:
@Nex' escreveu:Na minha opinião, se você tiver que checar muitas teclas no script e ele for muito grande, vale a pena por questões de legibilidade.
O melhor seria usar uma variável para dizer "Apertou a tecla! Não ative novamente até que solte!". Eu uso isso no MDPMv5 e Tuning Mod.

Na qual também fica mais dinâmico, pois não existe espera :v: enquanto você está segurando, todo o script continuará andando como se nada tivesse acontecido, a única mudança será que não ativará de novo até que você solte.
"mas gasta uma variável" eu poderia ter usado bits.

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Básico
Scripter CLEO - Básico
Mensagens : 1022
Reputação : 82
Desde : 04/03/2013
Idade : 17
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 10:46
@Junior_Djjr escreveu:E:
@Nex' escreveu:Na minha opinião, se você tiver que checar muitas teclas no script e ele for muito grande, vale a pena por questões de legibilidade.
O melhor seria usar uma variável para dizer "Apertou a tecla! Não ative novamente até que solte!".
Esse modo deve ser o melhor mesmo, eu fazia muito isso quando tava aprendendo philosoraptor

Edit: entendi agora a parada do AND/OR, mals
avatar
Veterano
Veterano
Mensagens : 2920
Reputação : 81
Desde : 31/07/2013
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 11:08
Código:
SCRIPT_START
{
NOP

LVAR_INT var1 var2 var3 var4 var5
WAIT 0

loop:
GENERATE_RANDOM_INT_IN_RANGE 0 100 var1
GENERATE_RANDOM_INT_IN_RANGE 0 100 var2
GENERATE_RANDOM_INT_IN_RANGE 0 100 var3
GENERATE_RANDOM_INT_IN_RANGE 0 100 var4
GENERATE_RANDOM_INT_IN_RANGE 0 100 var5

WAIT 0

IF IS_KEY_PRESSED VK_KEY_B
    CLEO_CALL continha var1 var1
    CLEO_CALL continha var2 var2
    CLEO_CALL continha var3 var3
    CLEO_CALL continha var4 var4
    CLEO_CALL continha var5 var5
    WHILE IS_KEY_PRESSED VK_KEY_B
        WAIT 0
    ENDWHILE
    PRINT_FORMATTED_NOW "Todas as variaveis sao 12: %d %d %d %d %d" 10000 var1 var2 var3 var4 var5
ENDIF

GOTO loop

}

{
    LVAR_INT var
    LVAR_INT cnc
    
    continha:
    var = cnc
        cnc -= var
            var += 12
    CLEO_RETURN 0 var
}
SCRIPT_END
Esse realmente não está compilando. philosoraptor

______________________________
I̜mpe͢r͚at̲ivoͯ, ͘no̅ mụnd̶o͋ ̺sl͟o͗w
́Co͔m͢ó ̼a ̒p̎eçͦa̲ ̖MC͝s ̚só͊ ͡faz̀em̈́ ̛s̸p͆ee͌df̡l̡owͭ
̟Pͭra ̌que̲ ä́ p̐r͜es̋s͉aͤ?
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Bicho Piruleta
Mensagens : 671
Reputação : 111
Desde : 22/09/2015
Idade : 19
Localização : Salvador - BA
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 11:10
@Elyzandro escreveu:
Código:
CLEO_CALL continha var1 var1
CLEO_CALL continha var2 var2
CLEO_CALL continha var3 var3
CLEO_CALL continha var4 var4
CLEO_CALL continha var5 var5
Esse realmente não está compilando. philosoraptor
Faltou o 0 em cada CLEO_CALL :

Código:
CLEO_CALL continha 0 var1 var1
CLEO_CALL continha 0 var2 var2
CLEO_CALL continha 0 var3 var3
CLEO_CALL continha 0 var4 var4
CLEO_CALL continha 0 var5 var5

______________________________
" Everyone gonna remember my name ! "
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 11:31
Quando eu faço para esquecer os "0" as pessoas levam ao pé da letra kkkkkkkkkkk

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Bicho Piruleta
Mensagens : 671
Reputação : 111
Desde : 22/09/2015
Idade : 19
Localização : Salvador - BA
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 11:48
:v:

______________________________
" Everyone gonna remember my name ! "
avatar
Veterano
Veterano
Mensagens : 2920
Reputação : 81
Desde : 31/07/2013
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 12:10
@Junior_Djjr escreveu:Quando eu faço para esquecer os "0" as pessoas levam ao pé da letra kkkkkkkkkkk
KKKKKKKKK pior que acho que foi isso que aconteceu mesmo.

______________________________
I̜mpe͢r͚at̲ivoͯ, ͘no̅ mụnd̶o͋ ̺sl͟o͗w
́Co͔m͢ó ̼a ̒p̎eçͦa̲ ̖MC͝s ̚só͊ ͡faz̀em̈́ ̛s̸p͆ee͌df̡l̡owͭ
̟Pͭra ̌que̲ ä́ p̐r͜es̋s͉aͤ?
avatar
Mensagens Nível 2
Mensagens Nível 2
Mensagens : 50
Reputação : 2
Desde : 14/03/2015
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 12:35
@Nex' escreveu:
Código:
IF CLEO_CALL KeyPressed 0 (0x4C) // VK_KEY_L
 value += 0.1
ENDIF
Hmm sério que esse if só vai retornar true se a tecla tiver apertada? pq?
avatar
Programador - Avançado
Programador - Avançado
Mensagens : 18775
Reputação : 342
Desde : 04/05/2012
Idade : 20
Link : gtamodvicio.blogspot.com
Ver perfil do usuáriohttp://gtamodvicio.blogspot.com

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 12:41
@Nex' escreveu:
@Junior_Djjr escreveu:Ohh, adição de +1 IF então fica pesado? Fica nada, uma checagenzinha é nada. Se cria mods de loops de 1000 linhas rodando a cada frame e mesmo assim não há perda de FPS Fuch That Guy
Com bastantes IF de resultados aleatórios tiraria bastante desempenho sim.
Concordo que não é bem o caso de um IS_KEY_PRESSED já que tem um padrão, na maioria das vezes o jogador não vai apertar as teclas.
Se tiver interesse nisso, leia aqui
(Link me ensinou isso ontem  :))

Mas se for ver, tem outros IFs internos do jogo gerando resultados aleatórios. philosoraptor

______________________________

Modifico quase qualquer coisa.   :)
------------------>>>http://gtamodvicio.blogspot.com/<<<------------------

Meu PC:
Spoiler:

Configurações PC:
*Processador: Intel Core i7 4790K 4.00GHz LGA1150
*Placa Mãe: GIGABYTE GA-H97M-D3H Intel (LGA1150)
*HD: 1TB Seagate Barracuda 64MB Sata III 7200RPM (2x - RAID 0)
*HD²: SAMSUNG M3 Externo USB 5400RPM 1TB
*Placa de vídeo: Nvidia GTX660 2GB DDR5 192bit EVGA
*RAM: 8GB DDR3 1600MHZ Kingston HYPER X BEAST (2x4GB)
*Fonte: Corsair 600W Reais CX600M Modular - CP-9020060-WW (80 Plus Bronze)
*Gabinete: Gabinete Raidmax Super Hurricane Branco - 248WB
*Monitor: LG 23MP55HQ Full HD HDMI 23'
avatar
Scripter CLEO - Básico
Scripter CLEO - Básico
Mensagens : 1022
Reputação : 82
Desde : 04/03/2013
Idade : 17
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 12:51
@Fabio escreveu:
@Nex' escreveu:
@Junior_Djjr escreveu:Ohh, adição de +1 IF então fica pesado? Fica nada, uma checagenzinha é nada. Se cria mods de loops de 1000 linhas rodando a cada frame e mesmo assim não há perda de FPS Fuch That Guy
Com bastantes IF de resultados aleatórios tiraria bastante desempenho sim.
Concordo que não é bem o caso de um IS_KEY_PRESSED já que tem um padrão, na maioria das vezes o jogador não vai apertar as teclas.
Se tiver interesse nisso, leia aqui
(Link me ensinou isso ontem  :))

Mas se for ver, tem outros IFs internos do jogo gerando resultados aleatórios. philosoraptor
Eu sei, não estou dizendo para não usar ifs ;-;
avatar
Programador - Avançado
Programador - Avançado
Mensagens : 18775
Reputação : 342
Desde : 04/05/2012
Idade : 20
Link : gtamodvicio.blogspot.com
Ver perfil do usuáriohttp://gtamodvicio.blogspot.com

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 13:00
@Nex' escreveu:
@Fabio escreveu:
@Nex' escreveu:
@Junior_Djjr escreveu:Ohh, adição de +1 IF então fica pesado? Fica nada, uma checagenzinha é nada. Se cria mods de loops de 1000 linhas rodando a cada frame e mesmo assim não há perda de FPS Fuch That Guy
Com bastantes IF de resultados aleatórios tiraria bastante desempenho sim.
Concordo que não é bem o caso de um IS_KEY_PRESSED já que tem um padrão, na maioria das vezes o jogador não vai apertar as teclas.
Se tiver interesse nisso, leia aqui
(Link me ensinou isso ontem  :))

Mas se for ver, tem outros IFs internos do jogo gerando resultados aleatórios. philosoraptor
Eu sei, não estou dizendo para não usar ifs ;-;

Não disse que você disse isso philosoraptor

Eu disse que provavelmente essa otimização do CPU não vai adiantar muito por causa da interferência do código do próprio jogo ;-:

______________________________

Modifico quase qualquer coisa.   :)
------------------>>>http://gtamodvicio.blogspot.com/<<<------------------

Meu PC:
Spoiler:

Configurações PC:
*Processador: Intel Core i7 4790K 4.00GHz LGA1150
*Placa Mãe: GIGABYTE GA-H97M-D3H Intel (LGA1150)
*HD: 1TB Seagate Barracuda 64MB Sata III 7200RPM (2x - RAID 0)
*HD²: SAMSUNG M3 Externo USB 5400RPM 1TB
*Placa de vídeo: Nvidia GTX660 2GB DDR5 192bit EVGA
*RAM: 8GB DDR3 1600MHZ Kingston HYPER X BEAST (2x4GB)
*Fonte: Corsair 600W Reais CX600M Modular - CP-9020060-WW (80 Plus Bronze)
*Gabinete: Gabinete Raidmax Super Hurricane Branco - 248WB
*Monitor: LG 23MP55HQ Full HD HDMI 23'
avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 13:20
@Rodrigo294 escreveu:
@Nex' escreveu:
Código:
IF CLEO_CALL KeyPressed 0 (0x4C) // VK_KEY_L
 value += 0.1
ENDIF
Hmm sério que esse if só vai retornar true se a tecla tiver apertada?  pq?
Por este motivo vou ter que fazer mais outro tutorial sobre condições, explicando mais a fundo o funcionamento de condições :v:
Lá dentro da função há um "IS_PC_VERSION" e em seguida retornou. Seria o mesmo de ter feito:
Código:
IF IS_PC_VERSION
 value += 0.1
ENDIF
Mas só passa pelo "IS_PC_VERSION" caso tenha pressionado a tecla. Portanto, se não tivesse pressionado, não seria assim. Retornaria falso.

Sei lá se esta explicação foi boa...

Você pode fazer esse tipo de coisa com CLEO_CALL e GOSUB.

Código:
IF GOSUB carro_existe
    //o carro existe
ENDIF

carro_existe:
DOES_VEHICLE_EXIST car
RETURN
É o mesmo de eu digitar:
Código:
IF DOES_VEHICLE_EXIST car
    //o carro existe
ENDIF

(possivelmente você não entendeu o motivo disso acontecer, mas entendeu como fazer pelo menos)

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Mensagens Nível 2
Mensagens Nível 2
Mensagens : 50
Reputação : 2
Desde : 14/03/2015
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 13:40
@Junior_Djjr vlw pela explicação  :)

@Junior_Djjr escreveu:(possivelmente você não entendeu o motivo disso acontecer, mas entendeu como fazer pelo menos)
Exatamente :v:
avatar
Mensagens Nível 4
Mensagens Nível 4
Mensagens : 411
Reputação : 12
Desde : 12/01/2016
Localização : 127.0.0.1:25565
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 13:45
É só lembrar que CLEO_CALL é o buraco negro do GTA.
avatar
Mensagens Nível 2
Mensagens Nível 2
Mensagens : 56
Reputação : 0
Desde : 19/01/2017
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sex 03 Fev 2017, 14:49
otimo tuto
avatar
Scripter CLEO - Intermediário
Scripter CLEO - Intermediário
Mensagens : 481
Reputação : 30
Desde : 08/02/2016
Localização : São Paulo
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Sab 25 Fev 2017, 18:25
Por que o programa não aceita um char como parâmetro?

avatar
Scripter CLEO - Avançado
Scripter CLEO - Avançado
Título : Não quero acreditar, quero saber.
Mensagens : 21852
Reputação : 666
Desde : 03/05/2012
Idade : 21
Localização : Ibitinga - SP
Link : www.MixMods.com.br
Ver perfil do usuáriohttp://MixMods.com.br

Re: 13. GOSUB e CLEO_CALL

em Dom 26 Fev 2017, 01:37
O certo devia você ter mostrado o função lá para ver se lá está em ordens, o que você fez com a var e tal.

______________________________

Mestre3224 voltou, ainda há esperanças no Youtube.
avatar
Scripter CLEO - Intermediário
Scripter CLEO - Intermediário
Mensagens : 481
Reputação : 30
Desde : 08/02/2016
Localização : São Paulo
Ver perfil do usuário

Re: 13. GOSUB e CLEO_CALL

em Dom 26 Fev 2017, 12:02
Pega todo o script logo kkkk. Estava refazendo aquele mod que postaram de 15 animações de morte aleatórias:

Script:
Código:
SCRIPT_START
{
    SCRIPT_NAME peddiea

    LVAR_INT scplayer
    LVAR_INT lv_char_targeted
    LVAR_INT lv_random
   
    GOSUB sub_load_anims
   
    GET_PLAYER_CHAR 0 scplayer

    label_1:
        WAIT 0

        IF NOT IS_PLAYER_PLAYING 0
            GOTO label_1
        ENDIF

        //NPC
        GET_CHAR_PLAYER_IS_TARGETING 0 lv_char_targeted
        IF DOES_CHAR_EXIST lv_char_targeted
            IF HAS_CHAR_BEEN_DAMAGED_BY_CHAR scplayer lv_char_targeted
            AND NOT IS_CHAR_IN_ANY_CAR lv_char_targeted
            AND NOT IS_CHAR_HEALTH_GREATER lv_char_targeted 10
                GENERATE_RANDOM_INT_IN_RANGE 0 8 lv_random
                IF NOT lv_random > 2
                    CLEO_CALL function_set_die_anim 0 (lv_char_targeted) ()
                ENDIF
            ENDIF
        ENDIF

        //Player
        IF NOT IS_CHAR_HEALTH_GREATER scplayer 10
        AND NOT IS_CHAR_IN_ANY_CAR scplayer
            GENERATE_RANDOM_INT_IN_RANGE 0 6 lv_random
            IF NOT lv_random > 1
                CLEO_CALL function_set_die_anim 0 (scplayer) ()
            ENDIF
        ENDIF

    GOTO label_1
}


    sub_load_anims:
        REQUEST_ANIMATION "KNIFE"
        REQUEST_ANIMATION "CRACK" 
        REQUEST_ANIMATION "WUZI"
        REQUEST_ANIMATION "FINALE"
        REQUEST_ANIMATION "MD_CHASE"
        REQUEST_ANIMATION "PARACHUTE"
        REQUEST_ANIMATION "RYDER"
        REQUEST_ANIMATION "SWEET"
    RETURN
}

{
    function_set_die_anim:
        LVAR_INT lv_char_anim
        LVAR_INT lv_random1
        LVAR_FLOAT lv_random2
       
        lv_char_anim = 0
        IF lv_char_anim = 1
            CREATE_CHAR 0 10 0.0 0.0 0.0 lv_char_anim
        ENDIF

        //Check anims
        IF HAS_ANIMATION_LOADED "KNIFE"
        AND HAS_ANIMATION_LOADED "CRACK"
        AND HAS_ANIMATION_LOADED "WUZI"
        AND HAS_ANIMATION_LOADED "FINALE"
        AND HAS_ANIMATION_LOADED "MD_CHASE"
        AND HAS_ANIMATION_LOADED "PARACHUTE"
        AND HAS_ANIMATION_LOADED "RYDER"
        AND HAS_ANIMATION_LOADED "SWEET"
            //Choice randim animation   
            GENERATE_RANDOM_INT_IN_RANGE 0 16 lv_random1
            GENERATE_RANDOM_FLOAT_IN_RANGE 1.5 4.0 lv_random2
            SWITCH lv_random1
                CASE 0
                    TASK_DIE_NAMED_ANIM lv_char_anim "KILL_KNIFE_PED_DIE" "KNIFE" lv_random2 1
                    BREAK
                CASE 1
                    TASK_DIE_NAMED_ANIM lv_char_anim "KNIFE_HIT_3" "KNIFE" lv_random2 1
                    BREAK
                CASE 2
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKDETH1" "CRACK" lv_random2 1
                    BREAK                                                               
                CASE 3
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKDETH2" "CRACK" lv_random2 1
                    BREAK
                CASE 4
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKDETH3" "CRACK" lv_random2 1
                    BREAK
                CASE 5
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKDETH4" "CRACK" lv_random2 1
                    BREAK
                CASE 6
                    TASK_DIE_NAMED_ANIM lv_char_anim "CS_Dead_Guy" "WUZI" lv_random2 1
                    BREAK                                                               
                CASE 7
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKIDLE2" "CRACK" lv_random2 1
                    BREAK
                CASE 8
                    TASK_DIE_NAMED_ANIM lv_char_anim "FIN_Land_Die" "FINALE" lv_random2 1
                    BREAK
                CASE 9
                    TASK_DIE_NAMED_ANIM lv_char_anim "CRCKIDLE4" "CRACK" lv_random2 1
                    BREAK
                CASE 10
                    TASK_DIE_NAMED_ANIM lv_char_anim "MD_BIKE_Lnd_Roll" "MD_CHASE" lv_random2 1
                    BREAK
                CASE 11
                    TASK_DIE_NAMED_ANIM lv_char_anim "MD_HANG_Lnd_Roll" "MD_CHASE" lv_random2 1
                    BREAK
                CASE 12
                    TASK_DIE_NAMED_ANIM lv_char_anim "MD_BIKE_Lnd_Roll_F" "MD_CHASE" lv_random2 1
                    BREAK                                                               
                CASE 13
                    TASK_DIE_NAMED_ANIM lv_char_anim "FALL_skyDive_DIE" "PARACHUTE" lv_random2 1
                    BREAK
                CASE 14
                    TASK_DIE_NAMED_ANIM lv_char_anim "Carhit_Tumble" "MD_CHASE" lv_random2 1
                    BREAK
                CASE 15
                    TASK_DIE_NAMED_ANIM lv_char_anim "Sweet_injuredloop" "SWEET" lv_random2 1
                    BREAK
                DEFAULT
                    BREAK                                                                                                                                                                                           
            ENDSWITCH
        ELSE
            GOSUB sub_load_anims
        ENDIF
    CLEO_RETURN 0 0
}
SCRIPT_END
Conteúdo patrocinado

Re: 13. GOSUB e CLEO_CALL

Permissão deste fórum:
Você não pode responder aos tópicos neste fórum