Página 1 de 2

Como criar scripts com CLEO+

Enviado: 12 Out 2020, 01:46
por Junior_Djjr
For english, use the translator jump menu at top of this page. Or if you prefer, simply use the documentation.

Tópico de sugestões de comandos: f16-utilidades/t2878-sugestoes-cleo-moonloader

Se você quer aprender a criar CLEO com gta3script (recomendado para CLEO+): f141-secao-tutorial-gta3script/t26-indi ... gta3script

NOVIDADE: Agora todos os comandos do CLEO+ estão bem documentados no Sanny Builder Library!
(lembrando que não é específico do Sanny Builder, inclusive usa o mesmo nome do gta3script)


O que é CLEO+?
CLEO+ (ou CLEOPlus) é um plugin que expande a CLEO Library, adicionando quase 300 novos comandos (3 vezes maior do que toda a CLEO! 6 vezes maior que a atualização da CLEO 4!), com funções realmente úteis, algumas que realmente revolucionam a maneira de criar mods CLEO.

Também inclui alguns dos principais do NewOpcodes.cleo, e todo o ClipboardCommands.cleo como retrocompatibilidade.

Eu (Junior_Djjr) crio mods CLEO desde 2011, quase 1 década, sou quem mais criou mods CLEO no mundo, e desde lá venho ensinando pessoas a criarem mods CLEO neste fórum, portanto, eu tenho total noção do que a CLEO precisa para ficar melhor, e pra isto eu iniciei este projeto.

Diferente de outros plugins para a CLEO, este foi focado em resolver e simplificar as operações mais simples, isto é, deixar a criação de mods CLEO ainda mais simples e agradável, para mods mais fáceis de serem criados, estáveis, menos propensos à bugs e conflitos. Sendo assim, iniciantes terão menos dificuldades, e experientes passarão menos raiva.

CLEO+ é somente para a versão 1.0 US do GTA San Andreas, inicialmente focado em GTA3script, mas também adaptado para Sanny Builder. E não aumenta o limite de variáveis, isto é trabalho pra CLEO em si ou o uso de outras gambiarras, mas adiciona excelentes funcionalidades para evitar tal limitação.


Isto não é uma documentação. Quase.
Eu escrevi isto em forma de tutorial + documentação, foi um texto pensando em "Olhe, agora você pode fazer isto!".
No entanto, agora há uma documentação de verdade no Sanny Builder Library (lembrando que não é específico do Sanny Builder, inclusive usa o mesmo nome do gta3script). Agradecimentos ao OrionSR por dedicar o tempo dele para documentar tudo.

 


Manipulação de scripts
STREAM_CUSTOM_SCRIPT_FROM_LABEL
Cria um novo custom script, como STREAM_CUSTOM_SCRIPT, mas usando uma label do seu script em vez do arquivo.
Isto traz realmente muitos benefícios: O novo script que será iniciado será independente, terá suas próprias variáveis etc, no entanto, compartilhará o exato mesmo espaço de memória do seu atual. Isto é muito bom para o desempenho, pois não causa fragmentação de memória e a inicialização do novo script é muito leve, diferente do STREAM_CUSTOM_SCRIPT que abre e lê um arquivo e tira uma cópia deste arquivo pra sua RAM etc. Perceba que, por estar no mesmo espaço de memória do script "pai", o script/thread memory será o mesmo. Em alguns casos, isto é muito útil para deixar o seu script "multi tarefas", ou até mesmo, recursivo, pois você pode criar quantos novos scripts/threads quiser.
Lembre-se também que, como o STREAM_CUSTOM_SCRIPT, você pode enviar variáveis ou valores quaisquer para o outro script, e esses valores cairão nas primeiras variáveis dele, semelhante ao CLEO_CALL, inclusive, você normalmente usará um novo escopo nessa nova label com as novas variáveis lá, semelhante ao CLEO_CALL.

GET_LAST_CREATED_CUSTOM_SCRIPT
Os comandos de criar um novo script não retornam o ponteiro do script criado, portanto, logo após criar um script, se você quer o ponteiro dele (sem precisar usar GET_SCRIPT_STRUCT_NAMED, que não é seguro, visto que vários scripts podem ter o mesmo nome), use isto. É ótimo para em seguida usar GET_SCRIPT_VAR e SET_SCRIPT_VAR.

GET_SCRIPT_VAR
SET_SCRIPT_VAR
Anteriormente chamados de GET_THREAD_VAR e SET_THREAD_VAR. Alterado pois o nome "thread" não faz sentido e caiu em desuso pela comunidade.
Lê ou escreve valores de uma variável de outro script/thread, excelente para um script controlar o outro.
Você simplesmente envia o ponteiro para o script (GET_LAST_CREATED_CUSTOM_SCRIPT, GET_SCRIPT_STRUCT_NAMED, GET_THIS_SCRIPT_STRUCT etc) e o ID da variável, onde a primeira variável definida é 0, lembrando que TEXT_LABEL ocupa 2 variáveis e TEXT_LABEL16 ocupa 4 variáveis, portanto, você deve pular elas na hora da contagem. no Sanny Builder é mais simples pois você trabalha diretamente com o número das variáveis.


Eventos
Isto irá literalmente mudar a maneira que você cria scripts CLEO!
Vamos supor que você queira recriar o cheat de "todos os pedestres com armas", antes da CLEO+, você rodaria todos os frames pegando todos os pedestres, checando se está sem arma, e colocando a arma nele. PÉSSIMO!!!
Com CLEO+ você simplesmente usa SET_SCRIPT_EVENT_CHAR_CREATE, assim, durante a criação de um CHAR, ele será enviado para esta label, e lá você dá a arma. Simples assim!
Isto é bom em todos os aspectos, o seu script fica mais organizado, avançado, estável e melhor performance.
A única limitação é que os eventos são "one shot", ou seja, eles são executados naquela label, e já precisam retornar o mais rápido possível para continuar processando o jogo, sem uso de WAIT.
Os comandos de eventos funcionam como "SET", ou seja, um toggle boolean onde você somente ativa ou desativa (lembre-se, para desativar, o comando precisa ser idêntico ao de ativar, para indicar que é o mesmo). Mas não entenda mal: Quando você liga um, ele realmente é criado, portanto, NUNCA use estes comandos em um loop!!! Você irá multiplicar os eventos.
Após o argumento da label, normalmente será necessário enviar uma variável, assim, tal evento armazenará o argumento nesta variável, em alguns casos, mais de uma. Você normalmente usará alguma variável temp qualquer. Internamente, a única coisa que o CLEO+ fará, é enviar o processo do seu script para esta label, e depois retornar para onde estava. Não há nenhuma diferenciação das variáveis fora do event, é simplesmente o mesmo script, mesmo escopo, ele só será executado temporariamente em outra região, muito simples.

RETURN_SCRIPT_EVENT
Retorna de um event. Events não suportam WAIT!

SET_SCRIPT_EVENT_SAVE_CONFIRMATION
Executado exatamente antes do jogo ser salvo. Você pode querer deletar todo o conteúdo do seu script que normalmente ficará preso no jogo salvo. Outra utilidade é implementar um sistema de salvar informações do seu script em algum arquivo no disco do jogador para ser reutilizado no próximo load. O argumento é o número ID do slot (espaço) a ser salvo.

SET_SCRIPT_EVENT_CHAR_CREATE
SET_SCRIPT_EVENT_CHAR_DELETE
Ao criar ou apagar um CHAR.

SET_SCRIPT_EVENT_CAR_CREATE
SET_SCRIPT_EVENT_CAR_DELETE
Ao criar ou apagar um CAR.

SET_SCRIPT_EVENT_OBJECT_CREATE
SET_SCRIPT_EVENT_OBJECT_DELETE
Ao criar ou apagar um OBJECT.

SET_SCRIPT_EVENT_ON_MENU
Durante o menu. A variável é setada como "1" caso acabou de pausar (no primeiro frame ao pausar), assim sendo facilmente útil tanto para executar algo logo durante a pausa, ou durante o processo do menu de pausa. Lembrando que o SCM não foi pensado em ser executado no menu, portanto é limitado (você não consegue desenhar textos, sprites etc durante o menu).

SET_SCRIPT_EVENT_CHAR_PROCESS
SET_SCRIPT_EVENT_CAR_PROCESS
SET_SCRIPT_EVENT_OBJECT_PROCESS
Ao processar determinada entidade. Este evento é executado em todas as pessoas, carros ou objetos naquele frame. Evite usar em objetos pois é comum haver centenas deles, leia mais dicas de otimização no BUILDING abaixo. Lembrando que nem todos os objetos do jogo são "OBJECT", os estáticos e mais importantes do mapa são "BUILDING", os "OBJECT" são, por exemplo, postes, lixeiras etc.
Em geral o desempenho é igual, ou muito pouco pior do que usar GET_ANY_*_RECURSIVE, portanto, se você tem dúvida entre GET_ANY_*_RECURSIVE ou EVENT_*_PROCESS, prefira o primeiro, mas muitas vezes a organização do código vale mais do que isso.
Outra coisa interessante é que o evento é executado logo antes da renderização deles, portanto, não existe nenhum atraso caso você queira por exemplo renderizar uma luz em um carro, a posição da luz, mesmo com o carro em movimento, será exata, diferente dos métodos convencionais.

SET_SCRIPT_EVENT_BUILDING_PROCESS
Como o de cima, mas para BUILDING. Isto é, objetos estáticos e importantes no mapa, que não são considerados "OBJECT", em outras palavras, CBuilding e não CObject. O argumento retornado será um ponteiro para o CBuilding, que não é nada mais nada menos que um CEntity. CLEO+ há alguns poucos comandos para ENTITY (procure), e o próprio jogo nunca implementa isto no SCM, portanto, se você realmente precisa trabalhar com BUILDING, normalmente você trabalhará com manipulação de memória.
Evite usar este evento, pois normalmente será executado centenas, senão milhares de vezes. Uma dica de otimização é desativar este evento caso a altitude da câmera seja muito alta, pois Project2DFX faz processar milhares de CBuilding quando você está voando alto, e normalmente você não precisará. Dentro dele, faça uma checagem bem específica para processar aquele BUILDING se for realmente necessário, por exemplo um ID de um modelo específico.

SET_SCRIPT_EVENT_CHAR_DAMAGE
Ao CHAR receber um dano qualquer. Normalmente você usará GET_CHAR_DAMAGE_LAST_FRAME para pegar as informações.

SET_SCRIPT_EVENT_CAR_WEAPON_DAMAGE
Ao CAR receber um dano de uma arma. Normalmente você usará GET_CAR_WEAPON_DAMAGE_LAST_FRAME para pegar as informações. Não é executado em colisões, para isto há outros comandos.

SET_SCRIPT_EVENT_BULLET_IMPACT
Ao ocorrer um impacto de tiro em qualquer local, qualquer coisa.
Há vários argumentos, e eles podem variar, lembre-se, nem sempre um tiro foi disparado por uma pessoa, nem atingido uma entidade, antes de tudo, cheque se os valores são válidos. Normalmente você usará GET_ENTITY_TYPE para saber se o atingido é um uma pessoa, carro etc.

SET_SCRIPT_EVENT_BEFORE_GAME_PROCESS
Início do processamento do jogo (antes de todos os scripts, e quase todo o jogo ser processado). Útil para casos bem específicos. Cuidado pois pode não ser muito seguro para scripts.

SET_SCRIPT_EVENT_AFTER_GAME_PROCESS
Final do processamento do jogo (depois de todos os scripts, o jogo já foi processado, renderizado etc). Útil para casos bem específicos. Cuidado pois pode não ser muito seguro para scripts.


Lista de valores (container)
Isto é uma implementação do std::list do C++, para os leigos, é como se fosse uma array dinâmico, ou seja, em vez de trabalhar com um espaço estático na memória, cada item pode estar num espaço qualquer, e tal lista de itens é navegada um por um. É menos otimizado para o desempenho, mas é uma maneira excelente de trabalhar com lista de valores que pode variar de tamanho e você não tem como prever.
É uma maneira excelente de armazenar e ler informações no seu script sem o uso de variáveis e thread/script memory (mesmo que thread/script memory seja mais aconselhável para o desempenho, sinceramente, uma solução mais high level é mais agradável de se trabalhar, né?)

CREATE_LIST
DELETE_LIST
Apaga ou cria uma lista de determinado data type.

LIST_ADD
LIST_ADD_STRING
Adiciona um valor à lista (INT ou FLOAT, caso seja uma texto direto, use a variação STRING, lembrando que um ponteiro pra uma string é um INT).

LIST_REMOVE_VALUE
LIST_REMOVE_STRING_VALUE
Remove todos os valores da lista baseado no valor específico que você enviou.

LIST_REMOVE_INDEX
Remove o valor na lista baseado num index, isto é, numa posição específica da lista.

LIST_REMOVE_INDEX_RANGE
Remove todos os valores na lista que estão entre 2 index, ou seja, início e fim.

GET_LIST_VALUE_BY_INDEX
GET_LIST_STRING_VALUE_BY_INDEX
Retorna o valor na lista baseado num index.

GET_LIST_SIZE
Retorna o tamanho total da lista, isto é, quantos itens tem.

REVERSE_LIST
Inverte todos os itens da lista; os últimos serão os primeiros;

RESET_LIST
Limpa a lista completamente, mas não a remove da memória. Use DELETE_LIST para apagá-la de verdade.

REPLACE_LIST_VALUE_BY_INDEX
REPLACE_LIST_STRING_VALUE_BY_INDEX
INSERT_LIST_VALUE_BY_INDEX
INSERT_LIST_STRING_VALUE_BY_INDEX
Substitui ou inserte um novo valor, dado um index da posição da lista. Assim você pode alterar o interior de uma lista sem precisar recriá-la etc.


Armazenar dados dentro de entidades
Você pode armazenar informações, como variáveis, dentro de uma pessoa, veículo ou objeto.
Trabalha como uma ponte que liga a função do plugin-sdk, muito útil para criar mods .asi, agora você pode utilizar em seus mods CLEO!
Por exemplo, um mod que você espirra perto de uma pessoa e ela é infectada, você armazena a informação da contaminação dentro da pessoa, e não dentro do seu script, assim, você pode, a qualquer momento, ler de novo aquela informação para saber se determinada pessoa está infectada ou não.
Eu recomendo que você leia o script teste da CLEO+ para entender como utilizar, pois é um conceito bem novo e peculiar.

INIT_EXTENDED_CHAR_VARS
INIT_EXTENDED_CAR_VARS
INIT_EXTENDED_OBJECT_VARS
Inicializa X variáveis internas naquela entidade. Você envia um identificador e número de quantas vars você precisa.
Normalmente você usará "AUTO" no identificador, assim a CLEO+ usará o ponteiro do seu script para determinar o valor do identificador, e automaticamente será um identificador único. Se você quer que a sua informação seja controlada por outros scripts, use um texto qualquer de até 99 caracteres, intermamente o texto será convertido para hash key.
Dica: visto que o "AUTO" usa o ponteiro do script como identificador, se outro mod quer trabalhar com o seu identificador, ele pode usar GET_SCRIPT_STRUCT_NAMED para pegar o ponteiro do seu script e usá-lo como identificador para assim controlar as mesmas variáveis daquele script, no entanto, isto é dependente do nome do script, e mais de um script pode ter o mesmo nome. Uma maneira melhor, principalmente se você está trabalhando com múltiplos scripts do mesmo mod, é usar GET_THIS_SCRIPT_STRUCT para pegar o ponteiro do seu script principal, e levar este valor para os seus outros scripts trabalharem no mesmo identificador.
Não fique inicializando todos os frames! O uso mais comum é antes checar se determinada variável existe com o GET, caso não exista, você usa o INIT para inicializar. Se por algum acaso você usar isto em uma entidade que já foi inicializada, os dados serão apagados e criados como novo, o que é ok, mas não é uma boa prática.

SET_EXTENDED_CHAR_VAR
SET_EXTENDED_CAR_VAR
SET_EXTENDED_OBJECT_VAR
Aqui você envia o identificador, o ID da variável (a primeira é "1") e o valor para escrever lá (INT ou FLOAT).

GET_EXTENDED_CHAR_VAR
GET_EXTENDED_CAR_VAR
GET_EXTENDED_OBJECT_VAR
Mesmo de cima, para retornar o valor.


Criar entidades sem prender no jogo salvo
CREATE_OBJECT_NO_SAVE
Além de criar um objeto que não salva junto com o jogo, o comando já implementa as opções de offset e posicionar o objeto automaticamente no chão. Perceba que a posição do chão vem de uma coordenada 3D, ou seja, se adapta caso esteja embaixo de uma ponte.

SET_CAR_GENERATOR_NO_SAVE
Marca um gerador de veículo estacionado para não salvar junto com o jogo.


Novo sistema de BLIPs
ADD_CLEO_BLIP
REMOVE_CLEO_BLIP
Cria um BLIP no mapa do radar usando um sistema totalmente novo. Eles não são salvos no jogo salvo, nem atingem o limite de BLIPs do jogo, ou seja, você pode usar à vontade, sem medo.
Ainda, possibilita pintar numa cor RGBA (perceba, inclui transparência), opção de aparecer somente perto ou longe, e a utilizar um RWTEXTURE qualquer como sprite do BLIP, isto quer dizer que você agora pode usar literalmente qualquer textura como BLIP, inclusive de um .txd de sprite de script, utilizando GET_TEXTURE_FROM_SPRITE. No entanto, neste caso não aparecerá na legenda do mapa (mas afinal, quem usa a legenda?).
Ah, mas você quer usar o ID de uma sprite original do jogo (por exemplo, ícone de save)? Sem problemas, simplesmente use, e neste caso a legenda funcionará.


Pegar uma textura a partir de um .txd de script
GET_TEXTURE_FROM_SPRITE
NewOpcodes.cleo implementou maneiras legais de ter controle à uma textura a partir de .bmp, .png e .dds, no entanto, não era compatível com instalação no ModLoader, nem a melhor maneira de trabalhar.
CLEO+ possibilita retornar uma textura (um ponteiro para RwTexture) a partir de um arquivo .txd, sim, daqueles que você coloca numa pasta "models/txd", totalmente compatível com ModLoader e facilmente trabalhado com Magic.TXD, podendo usar compressão, mipmaps etc (não use mipmaps para texturas/sprites usadas na interface!!!).
É simplesmente a sprite que você carrega com LOAD_TEXTURE_DICTIONARY e LOAD_SPRITE.
E esta textura pode ser usada de maneira interna no jogo, como trocar alguma textura do jogo por ela (desde que você consiga o acesso), ou para criar BLIPs personalizados com ADD_CLEO_BLIP citado acima.


Novo sistema de desenhar sprite/textura na tela.
DRAW_TEXTURE_PLUS
Não atinge os limites de sprites do jogo (que originalmente é 128 por script), você pode usar milhares.
Em vez de um ID de uma sprite, você usa uma textura diretamente (RWTEXTURE). Se você quer a sprite como no sistema nativo do jogo, use GET_TEXTURE_FROM_SPRITE para pegar a sprite do .txd que você carregou.
Enviando "0" no argumento de textura, simplesmente renderizará sem textura, igual ao DRAW_RECT.
Diferente do método nativo do jogo, este você NÃO precisa usar USE_TEXT_COMMANDS para atualizar a tela, é sempre atualizado automaticamente, basta deixar este comando rodando em loop todos os frames para que seja desenhado.
No argumento DRAW_EVENT você escolhe exatamente o momento que a sprite será desenhada na tela, ou seja, você pode desenhar na frente ou atrás da hud etc.
O argumento Depth é o eixo de profundidade da sprite, usado somente em sprites mascaradas. Você pode deixar 0.0.
FixAR corrige o aspect ratio, assim você não precisa usar GET_FIXED_XY_ASPECT_RATIO, o comando fará isto pra você, semelhante ao GTA V.
MaskVertCount e MaskVertArray é onde você define a máscara, se você não está utilizando o comando como máscara, simplesmente deixe "0". O trabalho com máscara não é tão user friendly, foi pensado em casos mais específicos: em count, é o número total de vértices, enquanto array é um ponteiro onde está armazenado todas as posições X e Y de cada vértice. A correção de aspect ratio não é feita, pois é basicamente impossível definir o "tamanho", visto que são posições cruas, assim, você terá que corrigir o AR você mesmo nos valores das posições, o que requer certa matemática.


Desenhar na tela
CONVERT_3D_TO_SCREEN_2D
Você envia uma coordenada 3D numa posição do mapa, e este comando retorna a posição 2D da tela do jogo, inclusive um valor de tamanho para você usar para desenhar um texto na tela que se adapta com a distância que o ponto 3D está.
Isto é exatamente (até um pouco melhor) o que a Rockstar North usou para realizar testes de depuração durante o desenvolvimento do jogo. Você pode querer usar, como eu usei no Real Traffic Fix, é de fato muito útil para testes.
Os argumentos CheckNearClip e CheckFarClip são para limitar a distância mínima e máxima. Você pode usar este comando com IF para saber se o ponto está dentro da visão mínima e máxima da câmera do jogo.

DRAW_STRING
DRAW_STRING_EXT
Os comandos DISPLAY_TEXT são péssimos para certos casos, pois ele pede um GXT, e antes de usá-lo, você precisa usar uma sequência de vários comandos para formatá-lo (sim, usar GOSUB com determinada formatação é uma boa, mas ainda chato). Este comando é um novo sistema, você envia de fato uma string, ou um ponteiro pra uma string, e nele mesmo, há as opções básicas de formatação, inclusive uma pré-formatação com bom visual, utilizando outline. Se não é o bastante, use a variação DRAW_STRING_EXT, que inclui todas as opções de formatação num único comando!
Perceba também que inclui o DRAW_EVENT, igual ao DRAW_TEXTURE_PLUS, isto é, você pode escolher exatamente o momento que será desenhado, antes ou depois do hud por exemplo, prefira usá-lo junto com DRAW_TEXTURE_PLUS se você quer desenhar fundos para o texto etc, e há também o FixAR, que corrige automaticamente o aspect ratio, para a fonte não ficar esticada em monitores widescreen.


Tarefas de pessoas (CHAR TASK)
Uma das coisas que deixa os mods CLEO muito instáveis, atrapalhando e causando bugs na inteligência artificial do jogo, como interrompendo ações dos pedestres etc, é justamente a falta de boas e fáceis maneiras de checar as tarefas atuais daquele CHAR, o que inclusive faz os modders usarem métodos ruins, como checar se está fazendo tal animação.
CLEO+ roda todas as pessoas do jogo naquele frame e guarda, como um cachê, a informação de quais tasks e situação daquela pessoa. Portanto, você pode utilizar aos milhares, a performance é ótima.

IS_CHAR_DOING_TASK_ID
Checa se o CHAR está fazendo uma task de determinado ID.
Isto é realmente muito útil, pois o jogo tem quase 400 tasks, e você pode checar todas elas para saber se determinado CHAR está fazendo determinada coisa. No entanto, não necessariamente a task prioritária, ele pode estar com uma task de matar alguém, mas no momento está simplesmente correndo por aí.
Você também pode querer dar uma olhada no GET_CHAR_PEDSTATE e GET_CHAR_SIMPLEST_ACTIVE_TASK, principalmente este último, que retorna a tarefa principal atual.

GET_CHAR_TASK_POINTER_BY_ID
Retorna o ponteiro de determinada task. Útil para fazer operações mais avançadas com a classe daquela task.
Abaixo há outros comandos mais específicos, prefira usá-los em vez deste, pois eles consideram mais de uma tarefa (ou seja, menos propenso à erros) e com performance ainda melhor. Também dê uma olhada no GET_CHAR_SIMPLEST_ACTIVE_TASK.

GET_CHAR_SIMPLEST_ACTIVE_TASK
Retorna a tarefa ativa mais "simples" de todas, basicamente, a principal. Por exemplo, há uma tarefa de uma pessoa matar a outra, não retornará a tarefa de matar, mas sim de estar correndo até a pessoa ou usando a arma.
Retorna o ponteiro mas também o ID dela, para uma fácil checagem de qual tarefa é. Isto é diferente da IS_CHAR_DOING_TASK_ID e GET_CHAR_TASK_POINTER_BY_ID pois elas consideram todas as tarefas, mesmo não sendo a principal.

GET_CHAR_KILL_TARGET_CHAR
Retorna o CHAR que determinado CHAR está tentando matar. Sério que o jogo não tinha um comando para isto??

IS_CHAR_USING_GUN
Checa se o CHAR está usando uma arma (não só segurando, mas de fato usando, ou seja, mirando ou atirando). Para somente atirando, use GET_CHAR_WEAPON_STATE.

IS_CHAR_FIGHTING
Checa se o CHAR está lutando.

IS_CHAR_FALLEN_ON_GROUND
Checa se o CHAR está caído no chão, por exemplo nocauteado.

IS_CHAR_ENTERING_ANY_CAR
IS_CHAR_EXITING_ANY_CAR
Checa se o CHAR está entrando ou saindo de algum carro.

IS_CHAR_PLAYING_ANY_SCRIPT_ANIMATION
Checa se o CHAR está realizando qualquer animação nomeada, isto é, normalmente de scripts. Útil para o seu mod não interromper as animações de outro mod ou algo assim.

IS_CHAR_DOING_ANY_IMPORTANT_TASK
Este comando é um monstro: Durante o cachê, CLEO+ considera se tal CHAR não está fazendo nenhuma tarefa importante, como matar alguém, correndo em pânico etc. Caso ele esteja "disponível para outras tasks", este comando retornará verdadeiro.
Esta explicação é simplista demais, mas pense assim: Este comando retorna verdadeiro caso o CHAR possa parar o que ele está fazendo para conversar com você. É basicamente isto. Útil para muitos mods, por exemplo, um mod que faz os pedestres atenderem o celular, ele não vai querer atender o celular enquanto ele está lutando contra alguém ou fugindo.
Há também a opção de incluir animações de script nesta checagem.
Você pode querer juntar este com o IS_CHAR_DOING_TASK_ID para adicionar mais exceções. Lembre-se, teste muito.

CLEAR_CHAR_PRIMARY_TASKS
Limpa todas as tarefas primárias (preserva as secundárias).

CLEAR_CHAR_SECONDARY_TASKS
Limpa todas as tarefas secundárias (preserva as primárias). É uma boa maneira de limpar as tarefas, como animações secundárias, sem atrapalhar na inteligência artificial do CHAR, visto que tarefas primárias são muito importantes.


Gradient noise
Gradient noise é uma excelente utilidade para diversos desenvolvimentos, principalmente gráficos e de jogos.
Consistente em uma geração de número aleatório que considera seus "vizinhos" para uma transição suave (degradê).
Por exemplo, eu utilizei isto para simular a vibração do motor e escapamento de carros com VehFuncs. Se eu tivesse usado uma geração aleatória qualquer, o efeito não seria natural.
Se você acha que não conhecia, na verdade você conhece muito bem: gradient noise é o coração do Minecraft. Você pode gerar mapas inteiros ou parciais (por exemplo, lixos no chão) utilizando gradient noise.

PERLIN_NOISE
Retorna o valor de um ponto do gradient noise utilizando o algorítimo "perlin noise" (mais especificamente, através do simplex noise).
Se você quer utilizar gradient noise de maneira mais simples possível, use este comando. Você simplesmente envia uma variável de progresso/offset que retornará um valor em torno de -1.0 e 1.0 (mas pode ultrapassar).
O valor enviado pode ser numa faixa de 10... 100... 1000... Depende do resultado que você quer. Normalmente você irá trabalhar em um loop, subindo ou abaixando suavemente uma variável, e terá o valor do noise retornado em uma outra. Há exemplo no script de teste da CLEO+.
O valor inicial pode ser considerado uma "seed"

PERLIN_NOISE_FRACTAL
PERLIN_NOISE_FRACTAL_2D
PERLIN_NOISE_FRACTAL_3D
Igual ao de cima, mas agora, com vários argumentos para você personalizar o resultado final. Se você não sabe por onde começar, teste: PERLIN_NOISE_FRACTAL 2 0.1 1.0 1.0 2.0 0.5 (f)
O "octaves" é um tanto interessante: à grosso modo ele mistura o noise mais de uma vez para retornar um resultado ainda mais natural. Indispensável para por exemplo gerar um terreno mais natural, mas há impacto negativo na performance, cada octave multiplica o cálculo.
Usar octave "1" os argumentos não serão importantes, exceto frequency, que define a frequência que os valores irão saltar.
No script teste da CLEO+ há literalmente um visualizador de perlin noise embutido onde você configura os valores e visualiza na tela em escala de cinza! Dê uma olhada.


Pegar entidades (carros, pessoas, objetos)
GET_ANY_CHAR_NO_SAVE_RECURSIVE
GET_ANY_CAR_NO_SAVE_RECURSIVE
GET_ANY_OBJECT_NO_SAVE_RECURSIVE
Finalmente eu tive a oportunidade de reinventar os comandos GET_RANDOM_*_NO_SAVE_RECURSIVE! Eu odiava eles.
Neste, retorna literalmente todas as pessoas, veículos ou objetos, sem exceções, sem checagem de distância, mas agora, utilizando uma variável que informa o progresso da busca.
O uso é simples: tenha uma variável tempo, seta-a para 0, e rode este comando em um WHILE usando-a no argumento de progresso. Num único WHILE você terá acesso às entidades (diferente da solução anterior que precisava de um IF e depois um WHILE), e o melhor: devido ao progresso da busca ser numa variável, isto resolve o problema do comando antigo da CLEO, que não havia como colocar um dentro do outro, neste, você pode usar quantos você quiser!
Veja no script de teste da CLEO+ um exemplo de uso, bem mais agradável. Mas lembre-se que CLEO+ tem events, e os events podem ser úteis para você caso o seu mod precise disso a todo o momento.

GET_CLOSEST_COP_NEAR_CHAR
Retorna o policial mais próximo de um CHAR numa distância limite. Muito útil para mods que precisam detectar se há um policial vendo a cagada de alguma pessoa. Há também filtro para incluir ou não à pé, de carro, e se está te vendo ou não!

GET_CLOSEST_COP_NEAR_POS
Mesmo de GET_CLOSEST_COP_NEAR_CHAR, mas agora é um policial próximo de certa posição.


Manipulação de memória
READ_STRUCT_OFFSET
WRITE_STRUCT_OFFSET
Mesma coisa do READ_MEMORY e WRITE_MEMORY, no entanto, inclui um offset que será somado, assim você transforma 2 linhas de código numa só, mais agradável e uma minúscula melhoria de desempenho, visto que é algo muito comum.

READ_STRUCT_OFFSET_MULTI
WRITE_STRUCT_OFFSET_MULTI
Mesmo de cima, mas agora além do offset (que pode ser 0, se você não precisa) ele lê e escreve múltiplas vezes. Você escolhe quantas vezes, e o tamanho a cada leitura ou escrita.
O melhor exemplo de uso é o seguinte: Imagine que você tem um ponteiro para uma coordenada XYZ e quer ler cada valor desta coordenada para 3 diferentes variáveis: READ_STRUCT_OFFSET_MULTI pCoord 0x0 3 4 (x y z). Simples assim.

READ_STRUCT_PARAM
WRITE_STRUCT_PARAM
Semelhante ao *_STRUCT_OFFSET mas em vez de um offset, é um index, que pula os bytes de 4 em 4.
Isto é, index 0 lerá os primeiros 4 bytes, index 1 lerá a partir do quinto byte. Isto é excelente para thread/script memory, pois é comum guardar uma sequência de dados de 4 bytes na thread/script memory, assim, você pode ler e escrevê-los baseado num index, o que é ótimo inclusive para o uso do REPEAT.
Dica: no index, use um CONST_INT para definir um nome para ele, o código fica bem organizado.

COPY_MEMORY
Copia o conteúdo da memória de um lugar pra outro com o determinado tamanho.

MAKE_NOP
Escreve uma sequência de NOPs (ou seja, em nosso caso, 0x90) em alguma região da memória para "apagar" a execução.
Anteriormente isto era feito através de várias linhas de WRITE_MEMORY, visto que o WRITE_MEMORY não é mais do que um memory set, portanto era necessário escrever vários "0x90909090" etc. Este comando simplifica o processo.


Renderizar objetos em um CHAR ou OBJECT
CREATE_RENDER_OBJECT_TO_CHAR_BONE
CREATE_RENDER_OBJECT_TO_CHAR_BONE_FROM_SPECIAL
DELETE_RENDER_OBJECT
Se você já tentou colocar um objeto na mão de um CHAR, conhece a dor de cabeça. O jogo é péssimo nisso, causa muitos problemas.
Esta nova solução você não cria um objeto, mas sim uma tarefa de renderização. CLEO+ irá renderizar aquele modelo durante a renderização daquela pessoa, como funcionam as armas do jogo.
Perceba que não há limites, você pode renderizar qualquer modelo do jogo (há algumas exceções que serão corrigidas) em qualquer parte do corpo de um CHAR, em qualquer rotação, tamanho, e até mesmo distorcer o objeto (igual à distorção 4D do Tuning Mod).
Você consegue até recriar a arma de um CHAR (dica: há uma flag no CPlayerData para esconder a arma, use em loop, mas somente player). Muito útil para objetos simples, como uma simples garrafa, quanto para criar trabalhos complexos como armaduras com super poderes.
A variação "FROM_SPECIAL" é para usar com "SPECIAL_MODEL", o que possibilita usar objetos carregados diretamente de um .dff e .txd (sem o uso de ID).

Da mesma forma, nas novas versões do CLEO+ há também para objetos:
CREATE_RENDER_OBJECT_TO_OBJECT
CREATE_RENDER_OBJECT_TO_OBJECT_FROM_SPECIAL

SET_RENDER_OBJECT_AUTO_HIDE
Para simplificar o seu script, use isto, você tem a opção da CLEO+ esconder automaticamente o objeto caso a pessoa morra, pegue uma arma ou entre num veículo. A tal tarefa de renderização continua existindo, só não fará nada.

SET_RENDER_OBJECT_VISIBLE
SET_RENDER_OBJECT_POSITION
SET_RENDER_OBJECT_ROTATION
SET_RENDER_OBJECT_SCALE
SET_RENDER_OBJECT_DISTORTION
Mais controles básicos. Usar distorção junto com rotação ou escala pode ter resultados estranhos.

Embaixo do capô: A variável do RENDER_OBJECT é um ponteiro para uma class interna do CLEO+, não vou dar ela inteira aqui pois ela pode sofrer alterações, mas se você precisa de um trabalho mais avançado e técnico no resultado, o offset 0 é o CPed, offset 4 é RpClump, offset 8 é o RwFrame, e 12 é o RpAtomic. Caso o modelo seja um clump, o frame e atomic serão 0, caso contrário, o clump que será 0.
Isto é útil para trabalhar com subobjetos da hierarquia, como funciona no Tuning Mod. Por exemplo, adicione um objeto num .ide usando "hier" para ser um objeto comum em forma de clump, o tutorial do Tuning Mod ajuda, sabendo trabalhar com clumps, você conseguirá controlar a rotação, posição e tamanho de cada objeto filho, podendo criar animações complexas etc.


Modo 2 jogadores
SET_CHAR_SECOND_PLAYER
DISABLE_SECOND_PLAYER
Uma maneira de ativar e desativar o segundo jogador a partir de um CHAR já criado. Foi importante para a ideia do Coop Storyline e Recruit 2 Player.

FIX_TWO_PLAYERS_SEPARATED_CARS
Todos os mods de 2 jogadores precisam implementar uma correção para que possibilite cada jogador entrar em carros separados, ou os mesmos, pensando nisto, a própria CLEO+ implementa essa correção, com excelente funcionamento, basta ativá-la com este comando.


Clima e ambientação
GET_CURRENT_WEATHER
GET_FORCED_WEATHER
GET_NEXT_WEATHER
SET_NEXT_WEATHER
GET_RAIN_INTENSITY
SET_RAIN_INTENSITY
O clima da ambientação do jogo é algo importante. Por que não havia o básico?

GET_CURRENT_HOUR
GET_CURRENT_MINUTE
Já existe GET_TIME_OF_DAY mas além de ser um nome um pouco confuso de encontrar, na gigante maioria das vezes você só vai precisar da hora, assim é interessante ter um comando separado para usar somente 1 variável.

GET_DAY_NIGHT_BALANCE
Retorna um valor entre 0.0 e 1.0, onde 0.0 é dia, 0.5 é tarde, 1.0 é noite. O valor é o mesmo usado para fazer a transição do pre-lighting do jogo e várias outras propriedades gráficas.

PASS_TIME
Passa determinado número de minutos, simulando uma real passagem de tempo, onde o relógio e calendário do jogo se ajusta completamente.
Por favor, se você quer por exemplo mudar o relógio do jogo de 6 horas para 10 horas, não só escreva o novo valor, prefira utilizar este comando, pois ele simula a passagem real, por exemplo os pickups do jogo terão o tempo considerado e até as nuvens do mod Real Skybox simularão uma nova rotação.


Checar se entidade é criada/controlada por script
IS_CHAR_SCRIPT_CONTROLLED
IS_CAR_SCRIPT_CONTROLLED
IS_OBJECT_SCRIPT_CONTROLLED
Assim você pode facilmente separa pessoas criadas por missões, scripts etc, dos pedestres aleatórios. Mesmo para carros e objetos.
CLEO não ter isto por padrão era um absurdo, pois é algo muitíssimo importante para seus mods não quebrarem o funcionamento de missões e outros mods.


Marcar entidade como criada/controlada por script
MARK_CHAR_AS_NEEDED
MARK_CAR_AS_NEEDED
MARK_OBJECT_AS_NEEDED
Assim, tal entidade não será deletada automaticamente pelo jogo (a não ser que algum outro mod CLEO mal feito marque-as ao contrário). Irão retornar verdadeiro para os comandos IS_*_SCRIPT_CONTROLLED.


Ajuste de resolução / aspect ratio / widescreen
GET_CURRENT_RESOLUTION
Retorna a resolução atual, útil para casos mais específicos.

[size=100]GET_FIXED_XY_ASPECT_RATIO[/size]
Algo praticamente indispensável caso você esteja desenhando algum conteúdo na interface, como uma sprite, quadrado etc.
O uso é muito simples: Você envia um valor X e Y, por exemplo o tamanho de um quadrado, e ele retorna o valor corrigido baseado no aspect ratio da resolução do jogo, assim, ao desenhar o tal quadrado, você utiliza os valores retornados, e assim ele realmente será um quadrado mesmo em resoluções widescreen. Como sempre, há exemplo no script teste da CLEO+.


Retornar tipo ou classe de entidade ou modelo
GET_ENTITY_TYPE
Retorna o tipo de entidade a partir de um ponteiro pra CEntity (chamado no CLEO+ simplesmente de ENTITY).
Veja a enum ENTITY_TYPE, basicamente você difere um veículo, de uma pessoa, de um objeto... Isto é útil quando você tem um ENTITY e precisa identificar o que exatamente aquilo é.
Um dos usos é: Você usa isto para checar se é uma pessoa, se é, use GET_PED_REF para retornar a referência como um CHAR para utilizar no script.

GET_MODEL_TYPE
Retorna o tipo de modelo a partir de um ID de modelo.


Mais checagens de input (botões, teclas)
IS_MOUSE_WHEEL_UP
IS_MOUSE_WHEEL_DOWN
Não era possível checar se a roda/scroll do mouse havia rolado, agora é. No entanto, lembre que em notebooks isto pode retornar verdadeiro muitas vezes por segundo.

IS_KEY_JUST_PRESSED
IS_BUTTON_JUST_PRESSED
Retorna se pressionou uma tecla ou botão somente naquele frame.
Se você trabalhou com mods CLEO pelo menos um pouco, deve estar sentindo um alívio. É, eu sei o que você sente.
Mas é importante lembrar que retorna somente naquele frame, isto é, se o seu loop tem 2 WAIT, o seu loop está rodando em 2 frames separados, na prática irá falhar 50% das vezes. Portanto tome cuidado com o uso dos WAIT.

GET_MOUSE_SENSIBILITY
Retorna a sensibilidade do mouse configurada no menu do jogo. Essencial para por exemplo criar um cursor in-game com a sensibilidade correta do jogador, ou qualquer coisa que requer ler o movimento do mouse, basta multiplicar o valor pela sensibilidade.

SET_CAMERA_CONTROL
Eu sempre estive inconformado com o fato do jogo não ter uma maneira de desativar somente o controle de câmera.

SET_PLAYER_CONTROL_PAD_MOVEMENT
Eu sempre estive inconformado com o fato do jogo não ter uma maneira de desativar somente o controle do player, preservando a câmera.

SET_PLAYER_CONTROL_PAD
E este aqui é a desativação total de um controle. POR FAVOR, PROCURE USAR ISTO EM VEZ DE SET_PLAYER_CONTROL!!! Pois este segundo, nativo do jogo, não só desativa o controle do player, mas o também deixa "seguro", ou seja, a polícia para de atirar em você etc, isto estraga o gameplay. SET_PLAYER_CONTROL_PAD faz somente o que diz, ou seja, desativa o controle, sem fazer nada além.

IS_AIM_BUTTON_PRESSED
Checa, de boa maneira, se o botão de mira está pressionado. Adaptado ao GInput. Lembre-se, botão, se você quer saber se está mirando, use IS_CHAR_USING_GUN.

IS_ANY_FIRE_BUTTON_PRESSED
Checa, de boa maneira, se o botão de tiro está pressionado. Adaptado ao GInput. Retorna também o tiro secundário. Lembre-se, botão, se você quer saber se está atirando, use GET_CHAR_WEAPON_STATE.

IS_SELECT_MENU_JUST_PRESSED
Checa, de boa maneira, se o botão de seleção foi pressionado neste exato momento. Isto é, a tecla de correr, ou X no controle de PS. Isto é muito útil pois dentro de um carro, o botão de seleção se torna o botão de acelerar, o que deixa tudo confuso. Este comando resolve tudo, ele considera o botão de correr (que por padrão é Espaço) mesmo dentro do carro!

GET_TIME_NOT_TOUCHING_PAD
Retorna o tempo desde que você não toca no controle, em milissegundos.


Controle de pickups
GET_PICKUP_THIS_COORD
Retorna algum pickup que esteja nesta coordenada. Não é comum, mas existe a possibilidade de existir mais de um na mesma posição, principalmente porque o jogo trabalha com uma coordenada compressada, portanto todos os pickups dentro de X metros estão na mesma posição.

GET_PICKUP_POINTER
Retorna o ponteiro para o CPickup, útil para trabalhos mais técnicos e internos através de manipulação de memória.

GET_PICKUP_MODEL
Retorna o ID do modelo do pickup. Prefira GET_PICKUP_TYPE se é melhor para o seu caso.

GET_PICKUP_TYPE
Útil para identificar se o pickup é uma arma, dinheiro etc sem checar o modelo em si.


Timers / contadores
DISPLAY_ONSCREEN_TIMER_LOCAL
DISPLAY_ONSCREEN_TIMER_WITH_STRING_LOCAL
DISPLAY_ONSCREEN_COUNTER_LOCAL
DISPLAY_ONSCREEN_COUNTER_WITH_STRING_LOCAL
CLEAR_ONSCREEN_TIMER_LOCAL
CLEAR_ONSCREEN_COUNTER_LOCAL
DISPLAY_TWO_ONSCREEN_COUNTERS_LOCAL
DISPLAY_TWO_ONSCREEN_COUNTERS_WITH_STRING_LOCAL
Todos os comandos de contadores de tempo e valores, agora adaptados para variáveis locais, pois nativamente só estão disponíveis em variáveis globais, o que atrapalha na criação de mods CLEO.
O funcionamento é exatamente igual aos de variáveis globais, ou seja, você envia uma variável e o valor dela será usado para contar, bem simples.
De bônus, perceba que os comandos "TWO", ou seja, 2 contadores, foram re-adicionados (eles foram removidos da versão final do jogo, então os re-adicionei como vars locais).

SET_ONSCREEN_COUNTER_FLASH_WHEN_FIRST_DISPLAYED_LOCAL
SET_TIMER_BEEP_COUNTDOWN_TIME_LOCAL
SET_ONSCREEN_COUNTER_COLOUR_LOCAL
Mais comandos de funções internas do jogo que não eram possíveis usar por comandos.


Situação do gameplay: missão, SAMP, save etc
IS_ON_MISSION
Checa se está numa missão, semelhante ao $ONMISSION == true do Sanny Builder, mas agora implementado da maneira mais correta, como o jogo implementou internamente, considerando diferente index da variável de missão.

IS_ON_SAMP
IS_ON_CUTSCENE
Se está durante o San Andreas Multiplayer; cutscene (filmes de missões).

IS_ON_SCRIPTED_CUTSCENE
Se está durante uma cutscene scriptada (aquelas cenas comuns durante as missões). Basicamente checa se o modo "widescreen" (que na verdade, é a tela cinematográfica) está ativa, onde o jogo normalmente a usa para estas cenas.

IS_GAME_FIRST_START
Checa se é a primeira vez que o jogo está iniciando naquele jogo salvo ou novo jogo. Isto é importante para casos específicos, principalmente se o seu script faz hook no jogo, você não vai querer que o hook seja feito mais de uma vez caso dar carregar ou iniciar um novo jogo.

GET_CURRENT_SAVE_SLOT
Retorna o ID do slot do save que você acabou de carregar. -1 caso seja novo jogo.
Muito útil para você salvar e carregar informações do jogo salvo em um arquivo local por exemplo, para assim o seu mod ter suporte ao salvamento de informações em cada jogo salvo através de um arquivo em vez de SAVE_THIS_CUSTOM_SCRIPT.
Se você pretende salvar informações ao salvar o jogo, use o comando SET_SCRIPT_EVENT_SAVE_CONFIRMATION.

IS_CHEAT_ACTIVE
Checa se tal cheat está ativo. Você consegue os IDs dos cheats aqui.

GET_LOCAL_TIME
Retorna a data completa do PC do jogador.

IS_HUD_VISIBLE
Checa se o hud está visível, de boa maneira.

IS_RADAR_VISIBLE
Checa se o radar/minimapa está visível, de boa maneira.

SET_ON_MISSION
É a mesma coisa de $ONMISSION = 1 no Sanny Builder, mas com uma prática mais correta e que funciona mesmo se o jogo estiver usando outro ID de variável global.


Câmera
GET_CURRENT_CAMERA_MODE
Retorna o modo de câmera atual. Há dezenas (veja o enum CAMERAMODE), mas muitas são só leftovers do desenvolvimento do jogo. Eu já usei muito para checar se está mirando, mas IS_CHAR_USING_GUN deve fazer um melhor trabalho.

GET_UNDERWATERNESS
Retorna o quão "embaixo d'água" a câmera está, entre 0.0 e 1.0.

GET_FADE_ALPHA
Retorna o alpha atual do fade sendo executado. Ou seja, 255.0 a tela está 100% preta (mas raramente atingirá exatos 255.0 pois normalmente logo em seguida começa um fade out, para ficar mais seguro, considere 200.0).

GET_OFFSET_FROM_CAMERA_IN_WORLD_COORDS
Retorna a coordenada num offset a partir da posição da câmera, por exemplo, "1.0 0.0 0.0" pegará a posição 1 metro para o lado direito da câmera. Mesma coisa de por exemplo GET_OFFSET_FROM_CAR_IN_WORLD_COORDS.

GET_THIRD_PERSON_CAMERA_TARGET
Uma função usada pelo jogo para determinar onde a arma está apontando com base num range e posição do char (normalmente o player), retornará o ponto inicial e final, como se fosse o trajeto de um tiro (não considera colisões).

GET_ACTIVE_CAMERA_ROTATION
Retorna a rotação da câmera. Simples assim. Por que diabos demorou 20 anos para alguém colocar isto?
Note que os valores retornados são um pouco mais complexos do que o esperado.

GET_CAMERA_STRUCT
Retorna o ponteiro para o TheCamera (CCamera) e ActiveCam (CCam), duas classes muito úteis, para você ter fácil acesso aos membros delas.

GET_CAMERA_ROTATION_INPUT_VALUES
SET_CAMERA_ROTATION_INPUT_VALUES
Finalmente agora você pode controlar a câmera por script! Especificamente, a câmera controlável.
Por exemplo, você pode usar GET para pegar os valores de input atuais, soma 90, dê SET e pronto, você girou a câmera 90 graus.


Matemática
CLAMP_FLOAT
CLAMP_INT
Clamp nada mais é do que uma limitação mínima e máxima de um valor. Em outras palavras, CLAMP_INT i 0 100 (i) é a mesma coisa de você fazer IF i < 0 ; i = 0 e IF i > 100 ; i = 100.
Não só para simplificar o seu código deixando-o mais organizado, mas tudo é executado de uma só vez, diferente do uso de IF que, em SCM, é uma operação muito complexa, e considerando que limitar o valor de uma variável é algo comum, esta otimização pode de fato fazer diferença.

EASE
Você envia um progresso linear (0.0~1.0) para retornar o valor alterado numa curva de ease.
É a mesma implementação do site easings.net, inclusive, as opções são as mesmas com os mesmos nomes. Entre lá para visualizá-las.
Isto é excelente para criar animações suaves.

GET_ANGLE_FROM_TWO_COORDS
Retorna o ângulo Z (heading) a partir de 2 coordenadas.

RANDOM_PERCENT
Você envia um número entre 0 e 100, a condição retornará verdadeira baseado nesta porcentagem, ou seja, 50 retornará verdadeiro em média 50% das vezes, simples assim.

GENERATE_RANDOM_INT_IN_RANGE_WITH_SEED
GENERATE_RANDOM_FLOAT_IN_RANGE_WITH_SEED
O mesmo comando de gerar um número aleatório, mas agora você pode enviar uma seed.
Se você não entende o conceito de seed, basicamente, a mesma seed sempre retornará o mesmo número aleatório. Isto é útil para você ter valores aleatórios, mas que sempre sejam os mesmos baseados numa seed.
E, internamente, o jogo já cria seeds para entidades, você pode pegá-las abaixo:

GET_CHAR_RANDOM_SEED
GET_CAR_RANDOM_SEED
GET_OBJECT_RANDOM_SEED
Retorna a seed da entidade, que é um número aleatório "único", pode ser útil para usar com GENERATE_RANDOM_*_IN_RANGE_WITH_SEED

GET_COORD_FROM_ANGLED_DISTANCE
Você envia uma coordenada, um ângulo e distância. Retorna a coordenada que está naquele ponto.

LERP
Interpolação linear entre 2 valores float. Por exemplo, A=1.0 e B=2.0, caso T seja 0.5, retornará o valor entre os dois, isto é, 1.5.
Dica: usar isto junto com EASE dá para fazer umas coisas bem legais, como movimentação de câmera, animação na interface etc.


Matrizes e quaterniões
Convertidos do NewOpcodes.cleo, possibilita trabalhar com matrix e quaternions, operações muito importantes para gráfico 3D, por exemplo, quaternion é a melhor maneira de rotacionar objetos sem o problema do gimbal lock. Matrix basicamente é o que indica a posição, tamanho e rotação do nosso objeto 3D.
É importante notar que absolutamente nenhum comando aqui irá alocar uma matrix ou quaternion para você, você envia um ponteiro com o espaço. Normalmente uma matrix você conseguirá lendo alguma class (por exemplo CObject+0x14 é a matrix do objeto; CMatrix e RwMatrix são essencialmente a mesma coisa), enquanto o quaternion você trabalhará com algum espaço de 16 bytes, em outras palavras, um quaternion nada mais é do que um vector4, ou seja, um XYZ com mais um float (normalmente chamando de W ou Real). Eu recomendo usar o ponteiro de uma variável (que tenha outras 3 variáveis disponíveis), ou melhor ainda, um thread/script memory com pelo menos 16 bytes disponíveis para usar como quaternion. Caso você esteja criando uma matrix do zero, são 72 bytes.

QUAT_SLERP
Você envia um progresso (0.0~1.0) para criar uma interpolação suave entre 2 quaternions.

SET_MATRIX_ROTATION_FROM_QUAT
SET_QUAT_FROM_MATRIX
Seta a rotação da matrix baseado num quaternion, ou pega um quaternion baseado numa matrix.

ROTATE_QUAT_ON_AXIS
ROTATE_MATRIX_ON_AXIS
Rotaciona o quaternion ou matrix num eixo e ângulo. Isto é a maneira mais correta de rotacionar algo, pois não causa o gimbal lock. Provavelmente você usará este comando mais de uma vez para ajustar a rotação, e normalmente você usará o axis como 0.0, -1.0 ou 1.0 para indicar a direção do eixo que você deseja rotacionar o determinado ângulo.

GET_NORMALISED_QUAT
Normaliza os valores do quaternion.

MULTIPLY_QUATS
Multiplica um quaternion por outro.

INITIALISE_QUAT
Inicializa um quaternion enviando os valores brutos. O mesmo pode ser feito com WRITE_OFFSET_MULTI, tanto que eu tive preguiça de converter o mesmo pro matrix.

CONVERT_DIRECTION_TO_QUAT
Este é o único que não veio do NewOpcodes.cleo. Este é um código que encontrei por aí para a Unreal Engine 4, se trata de uma função LookAt que você envia uma somente um vetor de direção e retornará um quaternion normalizado com a rotação para aquela direção.
Um ótimo uso é com o GET_COLPOINT_NORMAL_VECTOR, você consegue rotacionar algo baseado na rotação da face de colisão, para por exemplo criar um mod de cover ou pichar em qualquer lugar. No entanto me pareceu causar bugs ao enviar valores baixos, como 0.0~1.0, multipliquei por 10.0 e pareceu ok.

GET_MATRIX_X_ANGLE
GET_MATRIX_Y_ANGLE
GET_MATRIX_Z_ANGLE
Retorna os valores dos ângulos X, Y ou Z de uma matrix.

GET_OFFSET_FROM_MATRIX_IN_WORLD_COORDS
Retorna a coordenada num offset a partir da posição de determinada matrix, por exemplo, "1.0 0.0 0.0" pegará a posição 1 metro para o lado direito da matrix. Mesma coisa de por exemplo GET_OFFSET_FROM_CAR_IN_WORLD_COORDS.

SET_MATRIX_LOOK_DIRECTION
Faz uma matrix ser rotacionada em direção à outro ponto 3D. Similar ao Transform.LookAt da Unity Engine.



Operações com strings
Utilizar strings (textos) como ponteiros é algo muito comum na CLEO, portanto...

COPY_STRING
Copia uma string para a outra. Normalmente isto era feito com STRING_FORMAT, mas ele realiza operações de formatação, não queremos isto, portanto, COPY_STRING é mais otimizado para você copiar ou simplesmente criar uma string totalmente nova escrevendo ela para um ponteiro, por exemplo COPY_STRING "Test" (i).

GET_STRING_LENGTH
Retorna o tamanho total da string (até o null terminator, mas o null terminator não é incluído no resultado).
Se limita à 128, por segurança. Se retornar 128, provavelmente não é uma string válida. A condição retorna verdadeira caso retorne acima de 0.

IS_STRING_EQUAL
Checa se uma string é igual à outra.
O interessante aqui são as opções: tamanho máximo, diferenciar maiúsculas de minúsculas, e ignorar um caractere de sua escolha (por exemplo "test" e "t*st" com o caractere para ignorar "*" dará como verdadeiro para "tast").

IS_STRING_CHARACTER_AT
Checa se há determinado caractere em determinado index de uma string.

STRING_FIND
Encontra uma substring dentro de uma string. Implementação da mesma função do C++.
Por exemplo, "test.dff", você pode encontrar ".dff", dará verdadeiro e retornará o index do início onde foi encontrado. Há também opção de encontrar o primeiro, ou último, por exemplo se você quer encontrar a extensão de um arquivo, você procurar pelo último "." e não pelo primeiro.

CUT_STRING_AT
Uma maneira simples de cortar uma string em determinado index. Basicamente escreverá um null terminator (0) ali.

IS_STRING_COMMENT
Uma maneira simples de checar se uma string está comentada com "#", ";" ou "//", também considera espaços em branco. É muito útil caso o seu script suporte a leitura de um arquivo de configuração de formato próprio, assim, cada linha que você ler, use este comando.

SET_STRING_UPPER
SET_STRING_LOWER
Transforma uma string em todas maiúsculas ou todas minúsculas.


Sons
GET_AUDIO_SFX_VOLUME
GET_AUDIO_RADIO_VOLUME
Retorna o volume dos efeitos sonoros ou rádio configurados no menu do jogo. Indispensável para qualquer mod que carrega sons por arquivos, não deixe de usar, por favor!

GET_AUDIOSTREAM_INTERNAL
Retorna a referência interna de determinado AUDIOSTREAM para ser usado nas funções da bass.dll.
Isto possibilita o uso avançado de áudios, como o controle 3D, equalizador, spectrum, até mesmo o uso de plugins VST usados para produção de música! Veja aqui a documentação (a referência retornada para usar na bass.dll é um HSTREAM).


Efeitos especiais
GET_FX_SYSTEM_POINTER
Retorna o ponteiro para o efeito especial (FxSystem_c), útil para operações mais avançadas.

ADD_FX_SYSTEM_PARTICLE
Adiciona uma partícula baseada num efeito especial. Algo que incrivelmente não era possível por scripting.
Isto é muito útil, é assim que o jogo cria a maioria dos efeitos do jogo, como fumaças, sangue etc. No próprio comando, você tem várias opções, como cor e tamanho, portanto, você basicamente consegue criar novos efeitos especiais com isto, sendo muito útil para mods de super poderes por exemplo.
Algo que você tem que ter em mente é que por padrão o jogo deixa de criar muitas partículas em gráficos baixos, por exemplo, criando somente metade das partículas caso esteja nos gráficos Low. MixSets tem opção para ignorar isto, multiplicar, aumentando ou diminuindo. Portanto, teste o seu mod em diferentes configurações gráficas, e considere o uso ou desuso do MixSets.
Outra coisa a ser considerada é o argumento Brightness, se é algo não emissivo, por exemplo uma simples fumaça, considere ajustar o brilho com GET_DAY_NIGHT_BALANCE, para escurecer de noite.

IS_FX_SYSTEM_AVAILABLE_WITH_NAME
Checa se tal efeito especial existe com determinado nome. Finalmente você vai poder colocar um aviso e não causar crash para a pessoa caso esta pessoa não instale o seu mod de efeitos corretamente.


Ponto de colisão
GET_COLLISION_BETWEEN_POINTS
Você envia 2 coordenadas e será retornado várias informações sobre o ponto de colisão. Veja isto como "atirou num ponto, onde este tiro irá colidir?". Há muitas opções de filtragem, há até mesmo um EntityToIgnore que você envia o ponteiro de uma entidade (por exemplo, um ponteiro pra um char (CPed), car (CVehicle) ou objeto (CObject), que são filhos do CEntity), que o a checagem irá ignorá-los.
Algo importante para você notar, é que ele NÃO retorna um COLPOINT, mas sim você envia um ponteiro de um buffer para que o COLPOINT seja escrito. Esse buffer precisa ter pelo menos 44 bytes, ou seja, você pode usar um script/thread memory de pelo menos 44 bytes para isto. Caso não seja enviado, não retornará o COLPOINT, portanto é opcional.
Um COLPOINT pode ser usado para vários outros comandos da CLEO+.

GET_COLPOINT_COORDINATES
GET_COLPOINT_NORMAL_VECTOR
GET_COLPOINT_DEPTH
GET_COLPOINT_SURFACE
GET_COLPOINT_LIGHTING
A partir de um COLPOINT (obtido com GET_COLLISION_BETWEEN_POINTS) você pode ter várias informações, como a direção, material da superfície (se é grama etc, lembre-se, há muitos tipos de grama etc, você precisa pesquisar muito, eu uso Col Editor). A direção (NORMAL_VECTOR) é útil para mods como cover e pichação, que você precisa colocar algo na direção de uma parede por exemplo.

GET_CHAR_COLLISION_SURFACE
GET_CHAR_COLLISION_LIGHTING
GET_CAR_COLLISION_SURFACE
GET_CAR_COLLISION_LIGHTING
O próprio jogo já armazena informações do material e iluminação que determinada entidade está sob, portanto se você só quer saber das informações atuais que a entidade está colidindo (chão), use isto.


Distâncias
LOCATE_CAMERA_DISTANCE_TO_COORDINATES
LOCATE_CHAR_DISTANCE_TO_CHAR
LOCATE_CHAR_DISTANCE_TO_CAR
LOCATE_CHAR_DISTANCE_TO_OBJECT
LOCATE_CAR_DISTANCE_TO_OBJECT
LOCATE_CAR_DISTANCE_TO_CAR
LOCATE_OBJECT_DISTANCE_TO_OBJECT
LOCATE_CHAR_DISTANCE_TO_COORDINATES
LOCATE_CAR_DISTANCE_TO_COORDINATES
LOCATE_OBJECT_DISTANCE_TO_COORDINATES
LOCATE_ENTITY_DISTANCE_TO_ENTITY
Checa se determinada entidade ou câmera está dentro da distância limite. É semelhante aos outros LOCATE do jogo, mas este é circular/esférico em vez de retangular, ou seja, é de fato a distância de um ponto ao outro, e de bônus inclui para duas ENTITY e a câmera principal do jogo.
Inclusive, há performance melhor, um impacto praticamente nulo, inclusive sem utilizar raiz quadrada no cálculo.

GET_DISTANCE_MULTIPLIER
Retorna os multiplicadores de distância do jogo: LOD e geração. Este multiplicador é útil principalmente se você quer que seu mod se adeque às configurações de qualidade do player: o valor do LOD, por exemplo, é diretamente ligado com a distância de visão configurada no menu do jogo.


Carregamento de modelos
GET_MODEL_DOESNT_EXIST_IN_RANGE
Retorna algum ID de modelo inexistente dentro de um range inicial e final. Caso seja encontrado, a condição dá como verdadeira.
Foi pensado em conjunto com LOAD_SPECIAL_CHARACTER_FOR_ID, isto é, se você quer um ID de modelo temporário para usar em por exemplo num modelo de personagem especial, pegue algum ID disponível com este comando.
Recomendação: IF GET_MODEL_DOESNT_EXIST_IN_RANGE 15000 15024 (model)
Por organização, use o range de IDs 15000 até 15024, há 25 disponíveis, é o suficiente, mas você pode escolher usar outros. O problema é, se por exemplo algum mod de mapa já usa estes IDs, não estão disponíveis, portanto eu os reservei nesta página.
Por exemplo, se algum outro mod usar isto, este mod usará o ID "15000", e o seu mod "15001". Se o primeiro mod descarregar este modelo, completamente, ele voltará a estar disponível para usar novamente.

LOAD_SPECIAL_CHARACTER_FOR_ID
O mesmo de LOAD_SPECIAL_CHARACTER, mas você envia um ID de um modelo para o modelo especial ser guardado lá.
Isto foi pensado em conjunto com o GET_MODEL_DOESNT_EXIST_IN_RANGE, que retorna um ID disponível para você usar.
Note que isto de fato ADICIONA um novo ped ao seu jogo, portanto o limite de peds do seu jogo precisa ser aumentá-lo para poder usá-lo. Open Limit Adjuster é perfeito para isto pois ele aumenta o limite automaticamente.

UNLOAD_SPECIAL_CHARACTER_FROM_ID
Descarrega um modelo carregado pelo LOAD_SPECIAL_CHARACTER, semelhante ao UNLOAD_SPECIAL_CHARACTER, mas há um porém:
Use UNLOAD_SPECIAL_CHARACTER_FROM_ID após você deletar todos os chars que usam este modelo, pois, caso realmente for o último, CLEO+ descarregará o modelo completamente para que volte a estar disponível no GET_MODEL_DOESNT_EXIST_IN_RANGE. Caso contrário, o próprio jogo fará isto, algo que pode demorar muito tempo. REMOVE_MODEL_IF_UNUSED também ajuda.

REQUEST_PRIORITY_MODEL
Marca um modelo a ser carregado em modo de prioridade.

LOAD_ALL_PRIORITY_MODELS_NOW
Faz todos os modelos prioritários serem carregados, onde pode (mesmo que não sempre) ignorar os modelos não prioritários.
Eu recomendo altamente que você use isto em vez dos comandos nativos não-prioritários, pois LOAD_ALL_MODELS_NOW inclui realmente todos os modelos que o jogo está querendo carregar naquele momento, então você forçará os modelos a serem carregados, aumentando chances de lag spike. Separar em prioridade evita que modelos não importantes sejam carregados junto com o seu, assim evita lag spike no seu script (mesmo que, o melhor mesmo é esperar carregar em vez de usar LOAD_ALL_MODELS_NOW ou LOAD_ALL_PRIORITY_MODELS_NOW).

REMOVE_ALL_UNUSED_MODELS
Descarrega completamente da memória todos os modelos que não estejam sendo usado em nenhum lugar (não exista nenhum carro, pedestre etc com este modelo). Caso isto não seja usado, o modelo será descarregado automaticamente pelo jogo no momento que ele precisa de mais memória, o que, dependente do valor do streaming memory que o jogador configurou, pode ser rápido, ou nunca.
Este comando chamará uma função pesada, que fará um loop em praticamente todos os modelos do jogo, portanto, somente use se realmente necessário, e fora do gameplay, por exemplo durante um fade após uma missão ou algo assim.

REMOVE_MODEL_IF_UNUSED
Mesmo de REMOVE_ALL_UNUSED_MODELS, mas para um modelo específico.
No UNLOAD_SPECIAL_CHARACTER_FROM_ID, ele já faz isto automaticamente para que volte a estar disponível em GET_MODEL_DOESNT_EXIST_IN_RANGE.

IS_MODEL_AVAILABLE_BY_NAME
Checa se determinado modelo existe. Mesmo de IS_MODEL_AVAILABLE, mas por nome de .dff. Considera realmente qualquer arquivo do disco, mesmo não carregado como um ID.
Isto é muito útil para usar antes do LOAD_SPECIAL_CHARACTER_FOR_ID, assim, antes de tentar carregar determinado modelo baseado no nome, você pode saber se tal modelo realmente existe no disco (seja num .img ou no modloader).

GET_MODEL_BY_NAME
Encontra o ID de um modelo baseado no nome dele. Só use caso realmente necessário, evitando durante o gameplay, pois é uma função um pouco pesada.

LOAD_SPECIAL_MODEL
Uma revolução adicionada a partir do CLEO+ v1.2: Carregar arquivos .dff e .txd sem a necessidade de substituir IDs do jogo! Também não atinge outros limites e nem sequer consome parte do streaming (no entanto, por não usar streaming, não é recomendado usar em abundância, como props no mapa).
A ideia é para, principalmente, usar em scripts que requer objetos customizados. Pense em um mod de pesca, você vai querer infinitos modelos e texturas de peixes, ou até mesmo misturar um modelo de um peixe com textura de outro, e usar este modelo de peixe tanto para colocar na mão da pessoa, quanto para um objeto no mapa. LOAD_SPECIAL_MODEL é perfeito para casos assim!
Você dá o caminho do arquivo .dff e .txd (sem a extensão) e o CLEO+ irá carregar pra você instantaneamente (não usa streaming, portanto em alguns casos pode dar um leve stutter pra carregar arquivos pesados etc).

REMOVE_SPECIAL_MODEL
Caso já tenha algo usando este special model, somente abaixará uma contagem na referência. Quando algo parar de usar (por exemplo, um RENDER_OBJECT ser apagado), descarregará.

GET_SPECIAL_MODEL_DATA
Retorna o RpClump, RpAtomic e o index do TXD. Útil para usos mais específicos. Por exemplo, é possível adicionar um RpAtomic dentro de algum RwFrame para renderizar o objeto como peça de um carro (como o Tuning Mod).



Armas
GET_CHAR_WEAPON_STATE
Retorna o estado atual da arma atual do CHAR. Isto é, se está atirando ou recarregando.

IS_WEAPON_FIRE_TYPE
Checa se determinado ID de arma (WEAPON_TYPE) é de determinado tipo de tiro.
Isto é importante pois hoje é comum adicionar armas sem substituir, e antes era comum as pessoas checarem, por exemplo, se é arma de fogo pelo ID da arma. Este comando deixa o seu mod adaptado para armas adicionadas sem substituir.

GET_WEAPONINFO
GET_CURRENT_CHAR_WEAPONINFO
Retorna o ponteiro para o CWeaponInfo de tal arma, ou da arma atual da pessoa. CLEO+ tem vários comandos que trabalham com o WEAPONINFO, mas você também pode usar leitura de memória.

GET_WEAPONINFO_MODELS
Retorna os 2 modelos do WEAPONINFO que tal arma usa, útil para você carregá-los antes de criar a arma, assim sendo facilmente compatível com armas adicionadas sem substituir (você não precisa saber quais são os modelos necessários). Lembrando que algumas poucas armas, como carga explosiva, usa 2 modelos, a gigante maioria usa somente 1.

GET_WEAPONINFO_ANIMGROUP
Retorna o ID do grupo de animação do WEAPONINFO. É uma excelente maneira de você checar se tal arma é por exemplo uma shotgun, sendo compatível com armas adicionadas sem substituir.

GET_WEAPONINFO_FLAGS
Retorna o valor de todas as flags do WEAPONINFO. Em seguida, use os comandos de checar bits, por exemplo IS_LOCAL_VAR_BIT_SET_CONST, junto com o enum WEAPONINFO_FLAGS para checar as características daquela arma, por exemplo se é pistola dupla, se é pesada etc.

GET_WEAPONINFO_TOTAL_CLIP
Retorna a quantidade total que o pente da arma suporta.

GET_WEAPONINFO_FIRE_TYPE
Retorna o tipo de tiro da arma. Lembrando que IS_WEAPON_FIRE_TYPE lhe pode ser mais útil.

GET_WEAPONINFO_SLOT
Retorna o ID do slot que aquela arma ocupa no inventário.

GET_CHAR_WEAPON_CLIP
Retorna o pente atual da arma atual do CHAR.


Outras utilidades para o gameplay
FRAME_MOD
A condição retorna verdadeira a cada X número de frames (baseado no número interno do total de frames do jogo).
A utilidade é separar o trabalho do seu script em frames separados, isto é muito utilizado para otimizar a performance de jogos, por exemplo, IF FRAME_MOD 2 retornará verdadeiro 1 vez a cada 2 frames do jogo (ou seja, somente em frames de número par).
Internamente: if (CTimer::m_FrameCounter % arg == 0).

CHANGE_PLAYER_MONEY
Muda o dinheiro do player. No próprio comando você escolhe se você seta (ou seja, muda completamente, sem animação), adiciona, ou remove. Isto é uma maneira excelente de substituir o velho ADD_SCORE que está lá desde o GTA 2.


Outras utilidades para CHAR

FIX_CHAR_GROUND_BRIGHTNESS_AND_FADE_IN
Após criar um novo CHAR, use este comando para corrigir (com opções) a posição dele no chão (considera a coordenada 3D, portanto adaptado para embaixo de ponte etc), o brilho dele (sem mais chars sendo criados brilhantes ou escuros antes de tocar no chão), e aplicar um fade in, para ele aparecer suavemente na tela, semelhante ao fade out de quando ele desaparece.

SET_CHAR_COORDINATES_SIMPLE
SET_CAR_COORDINATES_SIMPLE
Posiciona uma entidade com valores crus e sem realizar nenhum outro cálculo de offset, inteligência artificial nem nada.
Perceba que isto é uma ótima maneira de corrigir pessoas e motos não aparecendo exatamente na posição que você coloca. Muito comum em motos, onde se você posicionar uma moto embaixo de um lugar não tão alto, a moto aparece em cima do teto, este comando resolve este problema em 100%.

IS_CHAR_REALLY_IN_AIR
O comando IS_CHAR_IN_AIR devia ser chamado de "FALLING", pois ele só retorna caso o CHAR esteja fazendo a tarefa de cair, muito pouco útil. Assim, eu fiz este novo comando que realmente retorna caso o CHAR esteja no ar, isto é, não colidindo com o chão.

IS_CHAR_ON_FIRE
Checa se o CHAR está pegando fogo. Há também uma task para isto, enquanto este checa diretamente o efeito de fogo dentro dele.

GET_CHAR_MAX_HEALTH
Sério que o jogo não tinha como pegar a saúde máxima de alguém? Também adaptado para o player.

GET_CHAR_HEALTH_PERCENT
Retorna a saúde do CHAR, mas em forma de porcentagem, ou seja, 0.0~100.0, utilizando a saúde máxima como base.

SET_CHAR_MODEL_ALPHA
Seta a transparência do modelo da pessoa.

GET_CHAR_WEAPON_DAMAGE_LAST_FRAME
Retorna as informações do último dano causado por uma arma no último frame. Prefira usar junto com SET_SCRIPT_EVENT_CHAR_DAMAGE visto que cada frame pode ter mais de um dano, assim com o event o funcionamento é mais confiável.

SET_CHAR_ARRESTED
Força o CHAR a ser preso. Só deve funcionar com player, mas é interessante principalmente para missões.

GET_CHAR_PEDSTATE
Retorna o estado atual do CHAR. Muito útil! Há uma lista muito grande que você pode usar para checar várias coisas, semelhante à checagem de tasks com IS_CHAR_DOING_TASK_ID, mas mais simplificada. Basta dar uma olhada no enum PEDSTATE.

GET_CHAR_PROOFS
Retorna a imunidade atual do CHAR. Importante caso você esteja usando SET_CHAR_PROOFS e não quera substituir as atuais.

IS_CHAR_WEAPON_VISIBLE_SET
Checa se o CHAR está com a visibilidade de arma setada, caso contrário, ele pode estar com arma, mas estar invisível (por exemplo a função de esconder arma dentro de carros do MixSets). Perceba que não checa se ele está com arma, é só a flag de visibilidade. É bom considerá-la em casos que você precisa identificar se uma pessoa viu a arma da outra.

GET_CHAR_STAT_ID
Retorna o ID do pedstat, isto é, você pode checar se tal CHAR é prostituta, médico, bombeiro etc. Também pode ser mais útil do que GET_PED_TYPE ao checar se um CHAR é polícia, pois algumas missões do jogo policiais são criados com pedtype de personagem de missão em vez de policial. Veja o enum STAT ou arquivo "data/pedstats.dat".

GET_CHAR_MOVE_STATE
Retorna o estado atual de movimento do CHAR, por exemplo, parado, andando ou correndo.

DONT_DELETE_CHAR_UNTIL_TIME
Adiciona um tempo para determinado CHAR não ser deletado, em milissegundos. Por exemplo "1000" ele não será deletado automaticamente por pelo menos 1 segundo.

GET_TIME_CHAR_IS_DEAD
Retorna há tantos milissegundos a pessoa está morta.

GET_CHAR_FEAR
Retorna o valor de "medo" do char, isto é, o quão covarde ele é.

GET_MODEL_PED_TYPE_AND_STAT
Returna o ped type baseado no ID do modelo de um ped. Antes de usar, certifique-se de que o ID do modelo é realmente um ped, com GET_MODEL_TYPE. Isto é útil para você criar um ped mas você somente sabe do ID dele, assim, com o ID você retorna o ped type correto (se é homem, mulher etc). Lembre-se do GET_CHAR_STAT_ID para pegar o stat do CHAR em si, em vez do modelo.


Outras utilidades para CAR
GET_VEHICLE_SUBCLASS
Retorna a subclass de tal veículo, assim, você pode diferenciar um veículo pelo seu tipo: se é um carro, caminhão monstro, moto, bicicleta etc. Basta utilizar os enum VEHICLE_SUBCLASS (dê uma olhada no .xml, por exemplo VEHICLE_SUBCLASS_BMX é para qualquer bicicleta).
Originalmente não era possível diferenciar uma moto de uma bicicleta, isto me deixava indignado. Agora com CLEO+ isto é finalmente possível.

GET_TRAILER_FROM_CAR
Sério que o jogo não tinha um comando para retornar o veículo que tal veículo está puxando?

GET_CAR_FROM_TRAILER
Sério que o jogo não tinha um comando para retornar o veículo que está tal veículo está sendo puxado?

CAR_HORN
Sério que o jogo não tinha um comando pra buzinar?

SET_CAR_ALARM
GET_CAR_ALARM
Manipular o alarme do carro, de todas as formas: você pode adicionar, e quando alguém entrar, dispara, ou disparar ou pará-lo, o mesmo para retornar, você sabe se um carro está com alarme ativo ou disparado.

GET_CAR_DUMMY_COORD
Retorna o a coordenada de tal dummy. Há opção para retornar a coordenada do mundo, ou offset a partir do centro do veículo.
Nota: está pré-adaptado ao VehFuncs, quando VehFuncs adicionar funcionalidade de dummies dinâmicos! Também deverá se adaptar ao Tuning Mod numa próxima atualizar do Tuning Mod.

GET_CAR_WEAPON_DAMAGE_LAST_FRAME
Retorna as informações do último dano causado por uma arma no último frame. Prefira usar junto com SET_SCRIPT_EVENT_CAR_DAMAGE visto que cada frame pode ter mais de um dano, assim com o event o funcionamento é mais confiável.

GET_CAR_COLLISION_INTENSITY
GET_CAR_COLLISION_COORDINATES
Retorna informações da última colisão que o carro teve. Foi indispensável para criar mods como o de ser jogado do para-brisa ou perder vida ao bater.

SET_CAR_MODEL_ALPHA
Seta a transparência do modelo do veículo.

SET_CAR_DOOR_WINDOW_STATE
Abre ou fecha os vidros dos carros. Lembrando que eles precisam ser adaptados como os originais do jogo, simplesmente irá aparecer e desaparecer. É a mesma função que faz os vidros se fecharem nos NPCs caso esteja chovendo por exemplo.

DOES_CAR_HAVE_PART_NODE
Checa se tal veículo tem um node, basicamente, uma peça, entre as peças principais do jogo. Isto é muito útil para mods de tuning checarem se o carro tem escapamento, pois não há uma maneira nativa de checar se tal carro pode realmente instalar um escapamento, assim evita crash. Mas é claro, muitas outras utilidades, só não tão útil: para simplificar, só retorna peças principais que o jogo usa, não serve para utilizar literalmente qualquer peça, pois para ser útil seria muitos outros comandos, então se você quer um controle mais a fundo de cada peça do carro, use NewOpcodes.cleo ou simplesmente trabalhe com manipulação de memória.

IS_CAR_REALLY_IN_AIR
Retorna verdadeiro caso o carro esteja no ar, ou seja, sem tocar no chão, de maneira confiável.

GET_CAR_PROOFS
Retorna a imunidade atual do CHAR. Importante caso você esteja usando SET_CAR_PROOFS e não quera substituir as atuais.

DONT_DELETE_CAR_UNTIL_TIME
Adiciona um tempo para determinado CAR não ser deletado, em milissegundos. Por exemplo "1000" ele não será deletado automaticamente por pelo menos 1 segundo.

GET_TIME_CAR_IS_DEAD
Retorna há tantos milissegundos o carro está destruído.

GET_CAR_ANIMGROUP
Retorna o ID do grupo de animação do veículo, inclui enum CAR_ANIMGROUP. É uma ótima maneira de entender qual é o tipo de veículo, mas evite ao máximo isto, pois pode mentir (por exemplo, isto é uma maneira de detectar que tal veículo é um caminhão, mas algum carro pode querer usar animação de caminhão, não sabemos). Se você quer usar isto para checar o tipo de veículo, só use se não há outra saída ou queira algo mais específico.

IS_CAR_OWNED_BY_PLAYER
SET_CAR_OWNED_BY_PLAYER
Checa e seta se algum player é "dono" de determinado veículo, isto é, ele pode entrar neste veículo sem a polícia pensar que é um roubo.
Aproveitando: para checar se um player é dono de um carro no Car Dealearship / GTA Brasil é CVehicle+0x42F 1 byte bit 7.

IS_CAR_CONVERTIBLE
Checa se um carro é conversível.

GET_CAR_VALUE
Retorna o valor monetário do carro (o quanto ele vale).
É o mesmo de GET_CAR_MODEL_VALUE, mas este retorna diretamente do handling, ou seja, mods como Tuning Mod podem alterar este valor, assim, é mais aconselhável usar este em vez de GET_CAR_MODEL_VALUE.

GET_CAR_PEDALS
Retorna os valores dos pedais do veículo, isto é, acelerador e freio.
Antes que digam que "break" está escrito errado, é que gta3script ao todo é inglês britânico, portanto eu quis preservar.


Outras utilidades para OBJECT
SET_OBJECT_MODEL_ALPHA
Set a transparência do modelo do objeto.

GET_OBJECT_CENTRE_OF_MASS_TO_BASE_OF_MODEL
Retorna o offset entre o centro de massa e base do modelo. O jogo usa isto como um offset para posicionar objetos mas nunca te dá acesso ao valor.

IS_OBJECT_REALLY_IN_AIR
Retorna verdadeiro caso o objeto esteja no ar, ou seja, sem tocar no chão, de maneira confiável.

GET_OBJECT_PROOFS
Retorna a imunidade atual do CHAR. Importante caso você esteja usando SET_OBJECT_PROOFS e não quera substituir as atuais.


Outros
GET_ENTITY_COORDINATES
GET_ENTITY_HEADING
Retorna a posição ou ângulo Z de alguma ENTITY (lembrando que o ponteiro pra um CHAR, CAR ou OBJECT é inclusive uma CEntity). Pode ser útil para retornar informações do event da BUILDING.

GET_MODEL_INFO
Retorna um ponteiro para o CBaseModelInfo, que pode incluir os filhos CVehicleModelInfo, CPedModelInfo, CWeaponModelInfo etc, dependente do tipo de modelo que ele é (GET_MODEL_TYPE). Muito útil para operações avançadas que requerem informações relacionadas aos modelos e não tenha comando para isto ainda.

READ_CLIPBOARD_DATA_TO
WRITE_CLIPBOARD_DATA_FROM
Lê e escreve informações no clipboard, isto é, CTRL+C CTRL+V.
É basicamente uma cópia de memória com um tamanho limite determinado por você.
O funcionamento provavelmente é idêntico ao ClipboardCommands.cleo do Deji. É retrocompatível com ele.

GET_LOADED_LIBRARY
O comando LOAD_LIBRARY carrega uma .dll, .asi, .cleo ou equivalente, não é nada legal para grande parte dos casos. Por exemplo, se você quer usar uma função de um .asi, você não quer recarregar ele, pois ele já está carregado!
Portanto, sempre considere usar este comando em vez do LOAD_LIBRARY. Também é excelente para checar se alguma .dll, .asi ou .cleo está instalado e carregado no jogo da pessoa. Por exemplo, IF GET_LOADED_LIBRARY "NewOpcodes.cleo" (i) você checa se NewOpcodes.cleo está instalado e carregado.
Retorna o ponteiro para uma biblioteca, caso exista, a condição retorna verdadeira.

RETURN_TIMES
A coisa mais ilegal que vocês verão em suas vidas de programador: retorna X vezes. Sim, se você chamar 2 GOSUB, um dentro do outro, e usar RETURN_TIMES 2, retornará os dois GOSUB ao mesmo tempo.
Este comando é seguro, portanto você pode usar por exemplo RETURN_TIMES 99999 que retornará o máximo possível sem problemas.

GET_CLOSEST_WATER_DISTANCE
Retorna a distância até o ponto de água mais próximo, e a altitude (Z) do ponto. São dois valores que o jogo calcula periodicamente para usar no som da água.
Se você tem um mod precisa ativar só caso esteja próximo da água, é altamente recomendado que, antes de fazer o seu script procurar por uma água, cheque se você está perto de uma, isto otimizará o desempenho do seu mod, pois procurar por água é um processo pesado.

GET_MODEL_NAME_POINTER
Você envia um ID de um modelo, e retornará o ponteiro para o nome dele.
Sim, só agora é possível ter acesso ao nome dos arquivos .dff do jogo! Isto porque agora CLEO+ guarda na RAM o nome de todos os modelos do jogo.
Note que se trata do ponteiro direto, não é uma cópia do nome, portanto não sobrescreva esses dados! Se precisar você pode usar COPY_STRING ou STRING_FORMAT.


WHILE TRUE, RETURN_TRUE e RETURN_FALSE
CLEO+ já inclui eles nas configurações do .xml. Foi só uma maneira de deixar o uso mais comum. Veja mais informações aqui. Lembrando que CONTINUE e BREAK precisam ser ativados na própria extensão no VSC, leia lá.

 

Re: Como criar scripts com CLEO+

Enviado: 13 Out 2020, 23:30
por kurt
achoq vou levar umas 5 horas pra ler com calma tudo isso, mais umas 2 semanas se quiser aprender, 
cara n entendo como tu consegue dedicar meses pra fazer isso '='

Re: Como criar scripts com CLEO+

Enviado: 14 Out 2020, 03:04
por Junior_Djjr
kurt escreveu:
13 Out 2020, 23:30
achoq vou levar umas 5 horas pra ler com calma tudo isso, mais umas 2 semanas se quiser aprender,
cara n entendo como tu consegue dedicar meses pra fazer isso '='
Foi basicamente 1 mês. 3 dias para escrever o post.

Re: Como criar scripts com CLEO+

Enviado: 15 Out 2020, 11:49
por Junior_Djjr
Troquei IS_CAR_BUS por LERP (interpolação linear), bem mais útil...
IS_CAR_BUS pode ser feito com GET_CAR_ANIMGROUP (animações bus e coach) ou diretamente nas flags no CVehicle ou handling.

Re: Como criar scripts com CLEO+

Enviado: 15 Out 2020, 22:52
por wooZ
Poxa,o comando GET_CHAR_KILL_TARGET_CHAR não está na versão atual do Cleo+?
Eu quero usar esse comando pra pegar o char que o player matar/atacar. Por enquanto tem algum outro jeito de fazer isso,ou é melhor esperar até a próxima versão?

Re: Como criar scripts com CLEO+

Enviado: 16 Out 2020, 07:13
por Junior_Djjr
wooZ escreveu:
15 Out 2020, 22:52
Poxa,o comando GET_CHAR_KILL_TARGET_CHAR não está na versão atual do Cleo+?
Eu quero usar esse comando pra pegar o char que o player matar/atacar. Por enquanto tem algum outro jeito de fazer isso,ou é melhor esperar até a próxima versão?
Só esperar a nova, logo logo.

Re: Como criar scripts com CLEO+

Enviado: 16 Out 2020, 16:47
por Junior_Djjr
Trocado GET_INTUNNELNESS por IS_SELECT_MENU_JUST_PRESSED, que é muito mais útil.

Caso ainda precise (é algo específico demais, eu duvido) é só ler 0x00C81334 (float), simples.

Re: Como criar scripts com CLEO+

Enviado: 17 Out 2020, 17:45
por Junior_Djjr
Trocado SET_SCRIPT_EVENT_PAUSE por SET_SCRIPT_EVENT_ON_MENU.
Acho que lançarei amanhã.

Re: Como criar scripts com CLEO+

Enviado: 18 Out 2020, 13:43
por Und
Vai lançar hoje?

Re: Como criar scripts com CLEO+

Enviado: 18 Out 2020, 22:14
por Junior_Djjr

Re: Como criar scripts com CLEO+

Enviado: 25 Out 2020, 01:04
por thalilmythos
IS_CAR_OWNED_BY_PLAYER

Does this opcode considers cars in garages owned by player?

Edit: Nevermind i already put it to the test and found my answer

Re: Como criar scripts com CLEO+

Enviado: 17 Dez 2020, 02:44
por XMDS
Hello, I have been using your CLEO+ plugin. I have three questions to ask:

1.0E0E This OP is to fix the offset of coordinates due to different screen sizes, widescreen and game windowing when drawing subtitles and textures?

0E0E=2,get_current_resolution_to %1d% %2d%



2.Regarding the problem of converting 0E3F from 3D to 2D coordinates on the screen.

I noticed that there is such code in the current OP source code:

Código: Selecionar tudo

//0E3F=4,convert_3d_to_screen_2d %1d% %2d% %3d% checkNearClip %4d% checkFarClip %5d% store_2d_to %6d% %7d% size_to %8d% %9d%


	RwV3d screenPos2D;
	float sizeX, sizeY;
 
	if (CSprite::CalcScreenCoors({ x, y, z }, &screenPos2D, &sizeX, &sizeY, checkFarClip, checkNearClip)) bResult = true;
 
	x = (screenPos2D.x / RsGlobal.maximumWidth) * 640.0f;
	y = (screenPos2D.y / RsGlobal.maximumHeight) * 448.0f;
	sizeX = (sizeX / RsGlobal.maximumWidth) * 8.0f;
	sizeY = (sizeY / RsGlobal.maximumHeight) * 8.0f;
Why use the transformed coordinates to divide by W and H, and multiply by 640 and 448. And why is the ratio of size 8.0?



3.I noticed that in your real-traffic-fix plug-in, 3D subtitles are created above the vehicle to display vehicle information. After converting the coordinates with the OP of 0E3F, I also used 033E:text_draw to create subtitles above the Ped. But the difference is that when I move the mouse to change the camera perspective, the subtitles will shift on the screen, leaving the original coordinates. And for the subtitles in your real-traffic-fix plug-in, when I move the camera perspective, the subtitles will only move at the center point above the vehicle (or the subtitles will be rotated at the center point)? How should I achieve this effect for you, not when the camera angle of view moves, the subtitles are shifted?

Re: Como criar scripts com CLEO+

Enviado: 17 Dez 2020, 03:09
por Junior_Djjr
XMDS escreveu:
17 Dez 2020, 02:44
1.0E0E This OP is to fix the offset of coordinates due to different screen sizes, widescreen and game windowing when drawing subtitles and textures?

0E0E=2,get_current_resolution_to %1d% %2d%
You don't need to. The game converts 640x448 coordinates for any resolution, but you may use GET_FIXED_XY_ASPECT_RATIO to fix proportions (size).
 
XMDS escreveu:
17 Dez 2020, 02:44
Why use the transformed coordinates to divide by W and H, and multiply by 640 and 448. And why is the ratio of size 8.0?
Above.
 
XMDS escreveu:
17 Dez 2020, 02:44
3.I noticed that in your real-traffic-fix plug-in, 3D subtitles are created above the vehicle to display vehicle information. After converting the coordinates with the OP of 0E3F, I also used 033E:text_draw to create subtitles above the Ped. But the difference is that when I move the mouse to change the camera perspective, the subtitles will shift on the screen, leaving the original coordinates. And for the subtitles in your real-traffic-fix plug-in, when I move the camera perspective, the subtitles will only move at the center point above the vehicle (or the subtitles will be rotated at the center point)? How should I achieve this effect for you, not when the camera angle of view moves, the subtitles are shifted?
I don't get it.

Re: Como criar scripts com CLEO+

Enviado: 17 Dez 2020, 04:02
por XMDS
Maybe my explanation is wrong. When I create 3D subtitles on top of the character. When I move the game perspective with the mouse, the actual position of the subtitles will shift with the perspective. But I found that with your real-traffic-fix plug-in, creating subtitles on top of the vehicle does not shift with the angle of view, but rotates around the center of the coordinates. How can I achieve the same effect?

Re: Como criar scripts com CLEO+

Enviado: 17 Dez 2020, 18:59
por Junior_Djjr
XMDS escreveu:
17 Dez 2020, 04:02
Maybe my explanation is wrong. When I create 3D subtitles on top of the character. When I move the game perspective with the mouse, the actual position of the subtitles will shift with the perspective. But I found that with your real-traffic-fix plug-in, creating subtitles on top of the vehicle does not shift with the angle of view, but rotates around the center of the coordinates. How can I achieve the same effect?
The use is simple, I don't understand how this effect could have happened, a video would help.
There is also an example of use in the CLEO+'s test script.