Página 1 de 2

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 19:59
por mythrillex
Pedestres pegam dinheiro no chão, esse mod eu quero fazer só que ando sem tempo então estou deixando a ideia aqui para sair do papel
Basicamente o sistema seria o seguinte, se tivesse dinheiro no chão e algum pedestre passasse perto iria fazer verificação se existe o pickup próximo e o pedestre pegaria o dinheiro, caso o jogador estivesse perto ele pegaria o dinheiro e sairia correndo(não sei como fazer essa parte ainda), senão ele pegaria e andaria como se nada tivesse acontecido..
basicamente já dei todo o sistema, só falta codar, e é algo bem interessante pro jogo, sempre achei que faltava isso.
vou terminar de estudar aqui(vida real) e vou ir mexendo no sistema pra deixar o mais completo possível com um radius de verificação entre o ped e o dinheiro e talvez um alarme pra se tiver muita grana no chão e um ped pegar vir outros correndo pegar os outros lotes

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 20:02
por Junior_Djjr
É realmente algo que demorou para alguém fazer...
É estranho ter dinheiro no chão e só você pegar.
Seria legal se ele antes fizesse animação de olhar pros lados para atravessar a rua, rapidamente, daí ele faz uma animação agachando para pegar algo (não sei qual, mas há mods que pegam armas do chão que usam alguma)

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 20:11
por mythrillex
Junior_Djjr escreveu: É realmente algo que demorou para alguém fazer...
É estranho ter dinheiro no chão e só você pegar.
Seria legal se ele antes fizesse animação de olhar pros lados para atravessar a rua, rapidamente, daí ele faz uma animação agachando para pegar algo (não sei qual, mas há mods que pegam armas do chão que usam alguma)
sim, é exatamente oq quero fazer.
meus mods eu faço em intervalos na aula eu tenho a documentação no celular e vou olhando as funções e adaptando no caderno e quando vou para casa faço debug no pc, por isso não estou focando tanto nos mods é mais uma passa tempo kk

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 20:27
por Junior_Djjr
Caso tiver algum pickup de dinheiro próximo, e naquele local do pickup não tiver nenhuma pessoa próxima, vá até ele, olhe para os lados e pegue.
Logo após pegar, checar por outros próximos, igual acima, mas agora sem fazer a animação olhando.
Melhor pegar uns 3 pickups próximos em vez de só 1, senão vai ficar fazendo animação abaixando toda hora e não será natural.
Após pegar tudo próximo, volta pro primeiro caso, onde caso encontrar de novo, olhe para os lados.

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 21:39
por mythrillex
Junior_Djjr escreveu: Caso tiver algum pickup de dinheiro próximo, e naquele local do pickup não tiver nenhuma pessoa próxima, vá até ele, olhe para os lados e pegue.
Logo após pegar, checar por outros próximos, igual acima, mas agora sem fazer a animação olhando.
Melhor pegar uns 3 pickups próximos em vez de só 1, senão vai ficar fazendo animação abaixando toda hora e não será natural.
Após pegar tudo próximo, volta pro primeiro caso, onde caso encontrar de novo, olhe para os lados.
já montei todo o sistema, agora só falta converter uma função cleo de transformar o pickup em objeto para eu obter o handle dele, pq é necessário para obter a proximidade entre o pedestre e o dinheiro (na verdade dá para fazer sem mas para deixar o código mais simples..) o ponto é que sem o handle não consigo fazer o pickup sumir por que não tem nenhuma variavel que me dê o pointer do money, só faz verificações com resultado boolean

achei essa função na internet mas não sei se ela funciona apenas com pickups ou se o moneypickup também se encaixa(se puder dizer antes de eu tentar converter isso ajudaria bastante)

Código: Selecionar tudo

 :Pickup2Object
    // 0@ - input param (pickup handle)
    // get pickup pointer
    0085: 1@ = 0@ 
    0A91: 3@ = 1@ / 65536
    0A90: 4@ = 3@ * 65536
    0062: 1@ -= 4@
    1@ *= 32
    1@ += 0x9788C0
    // read index
    0A8E: 4@ = 1@ + 0x1A
    0A8D: 4@ = read_memory 4@ size 2 virtual_protect 0
    if
        003B: 3@ == 4@
    then    
        // obtain pickup's object pointer
        1@ += 4
        0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
        if
            1@ > 0
        then
            // convert object pointer to a handle
            0A8D: 8@ = read_memory 0xB7449C size 4 virtual_protect 0
            0AA8: call_function_method 0x465070 struct 8@ num_params 1 pop 0 1@ 1@
            if
                03CA:   object 1@ exists 
            then
                0485: return_true
                0AB2: ret 1 1@
            end
        end
    end
    059A: return_false
    0AB2: ret 1 0
acho que nesse script terei que trabalhar com threads, são muitas coordenadas para fazer verificação kk

#edit
na verdade, agora que eu pensei, não sei como obter o handle do moneypickup pra converter ele em objeto kkkk eita
teria uma gambiarra que daria pra fazer bem legal, ao pedestres morrerem proximo ao jogador gerar pickups de money dentro do proprio script aí eu teria o pointer de cada money criado mas pra isso teria que fazer um mod para remover o drop de dinheiro ao matar npcs(para não ficar mta grana espalhada)

Pedestres pegam dinheiro

Enviado: 03 Mai 2018, 22:14
por Junior_Djjr
Essa função que você mandou devia cuidar disso, deve ser tudo oque você precisa mesmo.
Também poderia pegar a posição do pickup diretamente sem converter pra objeto (tem que ver como fazer isso), mas se converter pra objeto também tá ok, e é isso que ela faz.

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 01:02
por mythrillex
É acho que não vai dar ainda  de maneira eficiente..
dá para fazer o seguinte, criar uma esfera ao redor do jogador e ao um pedestre entrar no campo da esfera ele entrar para o grupo do jogador com a opção de seguir desabilitada
após isso fazer um thread esperando pela morte de tal pedestre, se ele morrer, criar um pickup de dinheiro e enviar o handle do pickup para alguma table.
depois do thread 1 fazer sua função que é esperar um jogador morrer para gerar um pickup editavel vem o thread 2 que ira criar uma esfera independente em cada posição de um pickup  da table usando um for e quando um pedestre passar perto acionar todo o sistema de animar, depois pegar o dinheiro, removendo o pickup e limpando o buffer, dessa forma funcionaria mas teria que ser um número limitado de drop de dinheiro para não ficar tão pesado
e gerenciar todas as animações e códigos sem usar waits(além do usado no loop principal) para não tirar a efetividade dos threads.

tudo isso se resolveria se existisse algum jeito de se obter o handle do pickup mas pelo que vi só é possivel usando funções do samp, creio que não descobriram os opcodes dos pickups completamente,  e como sou ruim no ollydbg acho que não vai dar tão bom apkosdap porém vou tentar fazer do jeito que expliquei a cima mas é de certeza que vai ficar muito lento, e se o jogo estiver usando gráficos pesados vai piorar

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 02:52
por Junior_Djjr
Caramba tudo isso só pra pegar um pickup? :pokerface: 

Eu tinha dado uma dica mas não funcionaria.

Onde você encontrou essa função acima?

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 06:06
por mythrillex
http://www.gtamodding.com/wiki/Pickup_to_object
o problema é que pra trabalhar com ela você já precisaria do handle do pickup, ou seja gerar o pickup no próprio script ou na teoria ter algum handle já pego

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 17:06
por Junior_Djjr
Ah, eu esqueci que eu já postei isso...  :ogw:
http://brmodstudio.forumeiros.com/t4929 ... mente-util

Código: Selecionar tudo

for 30@ = 0x9788C0 to 0x97D620 step 0x20
    if
        30@ > 0
    then
        0A8E: 31@ = 30@ + 0x1A
        0A8D: 31@ = read_memory 31@ size 2 virtual_protect 0
        31@ *= 0x10000
        0A8F: 29@ = 30@ - 0x9788C0
        29@ /= 0x20
        005A: 31@ += 29@

        //31@ = pickup
    end
end
Resolvido.

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 18:53
por mythrillex
:pokerface:

Código: Selecionar tudo

for i=0x9788C0, 0x97D620, 0x20 do
    if i > 0 then
        local x = i + 0x1A
        x = m.read(x, 2, false) -- memory.read(uint address, uint size, [bool unprotect=false])
        x *= 0x10000
        local y = i - 0x9788C0
        y /= 0x20
        x += y
        --x = pickup
        addBlipForPickup(x) -- addBlipForPickup(Pickup pickup) [add mark in pickup]
    end
end
fiz algo errado ? o script não está executando  :noob:

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 18:57
por Junior_Djjr
Ué, parece certo.
Mas como o script não está executando? Deu erro no código? (moonloader.log)

edit: na real esse código que passei não faz sentido, o início dele. :philo: 

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 19:19
por Junior_Djjr
ATENÇÃO: CÓDIGO FINAL POSTADO AQUI

Está funcionando aqui.

Código: Selecionar tudo

 {$cleo}
0000:

while true
    wait 0
    for 30@ = 0x9788C0 to 0x97D620 step 0x20
        0A8E: 31@ = 30@ + 0x1A
        0A8D: 31@ = read_memory 31@ size 2 virtual_protect 0
        31@ *= 0x10000
        0A8F: 29@ = 30@ - 0x9788C0
        29@ /= 0x20
        005A: 31@ += 29@
        
        if 09D1:   does_pickup_exist 31@
        then
            065B: store_pickup 31@ position_to 1@ 2@ 3@
            024F: create_corona_with_radius 1.0 type 2 lensflares 0 with_color 255 255 255 at 1@ 2@ 3@
        end
    end
end
Imagem
Mas tá retornando mesmo que o pickup não exista mais:
Imagem
Essas marcas são pickups "mortos", eles já existiram, não existem mais, mas continua os valores na memória (pois é assim que funciona).
Tem que fazer algo para checar se o tal pickup realmente existe, o 09D1: does_pickup_exist não funciona, e o mesmo comando em Lua com certeza também não funcionará.
 

Adicionado após 5 minutos 44 segundos:
Funcionou 100%:

Código: Selecionar tudo

 {$cleo}
0000:

while true
    wait 0
    for 30@ = 0x9788C0 to 0x97D620 step 0x20
        0A8E: 31@ = 30@ + 0x1A
        0A8D: 31@ = read_memory 31@ size 2 virtual_protect 0
        31@ *= 0x10000
        0A8F: 29@ = 30@ - 0x9788C0
        29@ /= 0x20
        005A: 31@ += 29@
        
        if 09D1:   pickup 31@ created
        then
            if 0AB1: call_scm_func @Pickup2Object 1 31@ 11@
            then
                01BB: store_object 11@ position_to 1@ 2@ 3@
                024F: create_corona_with_radius 1.0 type 2 lensflares 0 with_color 255 255 255 at 1@ 2@ 3@
            end
        end
    end
end

:Pickup2Object
// 0@ - input param (pickup handle)
// get pickup pointer
0085: 1@ = 0@ 
0A91: 3@ = 1@ / 65536
0A90: 4@ = 3@ * 65536
0062: 1@ -= 4@
1@ *= 32
1@ += 0x9788C0
// read index
0A8E: 4@ = 1@ + 0x1A
0A8D: 4@ = read_memory 4@ size 2 virtual_protect 0
if
    003B: 3@ == 4@
then    
    // obtain pickup's object pointer
    1@ += 4
    0A8D: 1@ = read_memory 1@ size 4 virtual_protect 0
    if
        1@ > 0
    then
        // convert object pointer to a handle
        0A8D: 8@ = read_memory 0xB7449C size 4 virtual_protect 0
        0AA8: call_function_method 0x465070 struct 8@ num_params 1 pop 0 1@ 1@
        if
            03CA:   object 1@ exists 
        then
            0485: return_true
            0AB2: ret 1 1@
        end
    end
end
059A: return_false
0AB2: ret 1 0
Sabendo que o objeto existe, você pode saber que o pickup também existe.

Agora passe tudo isso pra Lua :fts: 

ATENÇÃO: CÓDIGO FINAL POSTADO AQUI

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 19:21
por mythrillex
[19:20:51.116095] (error)    test.lua: F:\gtasa\moonloader\test.lua:58: '=' expected near '*'
[19:20:51.116095] (error)    test.lua: Script died due to an error. (078464CC)

que estranho, está dando erro nos operadores *=, /=
já tentei usar x = * x mas também dá erro, será que lua não faz cálculos em hex além da soma ?

tentei usar o do deathstroke tbm e dá o msm problema

Imagem

Pedestres pegam dinheiro

Enviado: 04 Mai 2018, 19:27
por Junior_Djjr
Converte para decimal então. Use qualquer ferramenta online, ou coloque o código no Sanny Builder, cursor de digitação em cima do número e CTRL+H para converter.

Uma coisa, logo antes do // obtain pickup's object pointer, na variável 1@ você tem o CPickup.
Não sei se você estudou sobre manuseamento de memória (especialmente sobre structs), mas:

Código: Selecionar tudo

00000000 CPickup         struc ; (sizeof=0x20, align=0x4, copyof_1198)
00000000                                         ; XREF: .data:CPickups::aPickUps/r
00000000 m_fRevenueValue dd ?
00000004 m_pObject       dd ?                    ; XREF: CPickups::GenerateNewOne(CVector,uint,uchar,uint,uint,bool,char *)+285/r
00000004                                         ; CPickups::GenerateNewOne(CVector,uint,uchar,uint,uint,bool,char *)+292/r ... ; CObject *
00000008 m_nAmmo         dd ?
0000000C m_nRegenerationTime dd ?
00000010 m_vecPos        CompressedVector ?      ; XREF: CPickup::GetPosn(void)+1/r
00000010                                         ; CPickup::GetPosn(void)+5/r ...
00000016 m_nMoneyPerDay  dw ?
00000018 m_nModelIndex   dw ?
0000001A m_nReferenceIndex dw ?
0000001C m_nPickupType   db ?                    ; XREF: CRunningScript::ProcessCommands1100To1199(int)+AB4/r
0000001D m_nFlags        db ?                    ; flags
0000001E _pad1E          db 2 dup(?)
00000020 CPickup         ends
Aparentemente em +0x1C você tem o tipo de pickup, e é lá que deve estar o tipo "dinheiro". Não sei qual o número do dinheiro mas você consegue descobrir com testes.
Senão cheque o modelo do objeto, mas a forma acima é a mais correta (especialmente porque você não precisa pegar o objeto de todos os pickups do jogo né, você só quer o de dinheiro).
Edit: em +0x18 também tem o ID do modelo :philo: é legal também.