Jump to content

[SA] CLEO. Is it possible to get rope length for heli (Leviathan) ? [SOLVED]


vladvo

Recommended Posts

I tried everything, but I failed. As far as I understand - the rope from Leviathan to magnet is not an 'object'. Still, in IDA there is this code:
 

006D3D10
.text:006D3D10                             ; =============== S U B R O U T I N E =======================================
.text:006D3D10
.text:006D3D10
.text:006D3D10                             ; double __thiscall CVehicle::GetRopeHeightForHeli(void *this)
.text:006D3D10                             _ZN8CVehicle20GetRopeHeightForHeliEv proc near
.text:006D3D10 000 83 C1 1D                                add     ecx, 1Dh
.text:006D3D13 000 51                                      push    ecx             ; id
.text:006D3D14 004 E8 E7 22 E8 FF                          call    _ZN6CRopes8FindRopeEj ; CRopes::FindRope(uint)
.text:006D3D19 004 69 C0 28 03 00 00                       imul    eax, 328h
.text:006D3D1F 004 83 C4 04                                add     esp, 4
.text:006D3D22 000 D9 80 D4 6B B7 00                       fld     _ZN6CRopes6aRopesE.m_dwHeight[eax] ; CRopes::aRopes
.text:006D3D28 000 C3                                      retn
.text:006D3D28                             _ZN8CVehicle20GetRopeHeightForHeliEv endp

Judging by presence if ___thiscall - the right opcode to use is 0AA8.  I tried  passing everything - heli handle, heli struct, magnet handle, magnet struct. Nothing. Screws camera. 
When I hover cursor over *this it shows xref to CCam::Process_1rstPersonPedOnPC(CVector const&,float,float,float)+54. 
I am totally confused. I guess the rope is a graphical 'something', but it is still handled by the game. Is it possible to get the rope lenght ?
And the most important part of the question - is there a really good guide on how to use 0AAx opcodes and call functions ?

Edited by vladvo
Link to comment
Share on other sites

@vladvo

I got the same result. When I use this function in the other language it works fine. In scm it just freezes like you described. 
Now on the rope lenght issue:
Although we got the opcode 0796 which assumes we already have magnet handle (which is btw not $Crane_Magnet) and even if we do we also need to check if it'a attached to a vehicle. 
To do all that we need to use CRope class. 

The magnet object used by #LEVIATHN heli is defined as 3053 - INDUS_MAGNET so lets define what we have so far:

Spoiler
const
    INDUS_MAGNET = 3053
    CRopeStruct = 0x556AE2  //  example pointer to  _ZN6CRopes6aRopesE 
end

Now, the game has a limit of 8 ropes (0 - 7) used at once. Each rope object is 0x328 size and it starts at:

0xB768B8    //  _ZN6CRopes6aRopesE

so the iteration loop might come in handy:

for 30@ = 0 to 7 step 1
    
end

Any of these 8 ropes can be used for the magnet so lets start checking which is it. So first lets check if there's a rope attached to an entity:

Spoiler
for 30@ = 0 to 7 step 1  
    0085: 7@ = 30@
    0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration 7@ result_to 3@ //  CEntity *m_pRopeHolder; 
    if 3@ <> 0
    then
        //  there's an entity attached at one or more ropes
    end
end
:readMemoryOffsetWithIterr
//  0@ CRopeStruct; 1@ offset; 2@ iteration
2@ *= 0x328 //  CRope struc size
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
005A: 31@ += 1@
005A: 31@ += 2@
0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0
0AB2: cleo_return 1 31@

Now lets check if that rope has our magnet:

Spoiler
for 30@ = 0 to 7 step 1  
    0085: 7@ = 30@
    0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration 7@ result_to 3@ //  CEntity *m_pRopeHolder;   
    0085: 7@ = 30@
    0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x314 iteration 7@ result_to 4@ //  CObject *m_pRopeAttachObject;
    if and
        3@ <> 0
        4@ <> 0 
    then
        3@ += 0x22
        0A8D: 3@ = read_memory 3@ size 2 virtual_protect 0  //  CEntity *m_nModelIndex;
        4@ += 0x22
        0A8D: 4@ = read_memory 4@ size 2 virtual_protect 0  //  CEntity *m_nModelIndex;
        if and 
            3@ == #LEVIATHN
            4@ == INDUS_MAGNET
        then 
            //  there're two entities attached to a rope
            //  a heli with the ID 417 and the magnet of ID 3053 
        end   
    end
end
:readMemoryOffsetWithIterr
//  0@ CRopeStruct; 1@ offset; 2@ iteration
2@ *= 0x328 //  CRope struc size
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
005A: 31@ += 1@
005A: 31@ += 2@
0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0
0AB2: cleo_return 1 31@

and now we can check its lenght:

Spoiler
const
    INDUS_MAGNET = 3053
    CRopeStruct = 0x556AE2  //  pointer to  _ZN6CRopes6aRopesE 
end

while true
    wait 0
    for 30@ = 0 to 7 step 1  
        0085: 7@ = 30@
        0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration 7@ result_to 3@ //  CEntity *m_pRopeHolder;   
        0085: 7@ = 30@
        0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x314 iteration 7@ result_to 4@ //  CObject *m_pRopeAttachObject;
        if and
            3@ <> 0
            4@ <> 0 
        then
            3@ += 0x22
            0A8D: 3@ = read_memory 3@ size 2 virtual_protect 0  //  CEntity *m_nModelIndex;
            4@ += 0x22
            0A8D: 4@ = read_memory 4@ size 2 virtual_protect 0  //  CEntity *m_nModelIndex;
            if and 
                3@ == #LEVIATHN
                4@ == INDUS_MAGNET
            then         
                0085: 7@ = 30@
                0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x31C iteration 7@ result_to 3@ //  float m_fRopeSegmentLength;
                
                0087: 1@ = 3@
                1@ *= 10.0
                0092: 1@ = float_to_integer 1@
                03F0: enable_text_draw 1
                045A: text_draw_1number  50.0  100.0 'NUMBER' 1@
                    
                //  8 - 0     where 8 is the shortest rope value which is odd
            end
        end
    end
end 
:readMemoryOffsetWithIterr  
//  0@ CRopeStruct; 1@ offset; 2@ iteration
2@ *= 0x328 //  CRope struc size
0A8D: 31@ = read_memory 0@ size 4 virtual_protect 0
005A: 31@ += 1@
005A: 31@ += 2@
0A8D: 31@ = read_memory 31@ size 4 virtual_protect 0
0AB2: cleo_return 1 31@

Although in c++ this whole thing can be done in a single line:

float ropeHeight = playa->m_pVehicle->GetRopeHeightForHeli();

It could probably be done within the scm as well with the fnc you provided - I just don't know how.

 

EDIT: @Wesser I was wondering what that opcode is doing. I wish you're here more often. 

Edited by Jack
Link to comment
Share on other sites

You are supposed to pass a CVehicle pointer and then pop a floating-point value from the stack using POP_FLOAT (2793) command.

  • Like 2
Link to comment
Share on other sites

@vladvo i have a tiny info which you may adapt or use as a reference.. i found this global variable in Sanny Builder's help folder "CustomVariables.ini" .. it maybe useful for you 🙂

 

10496=Crane_Rope_Length

 

Link to comment
Share on other sites

4 hours ago, ArmanCan said:
10496=Crane_Rope_Length

Thanks, but a crane is a crane. This var works only for crane.

Link to comment
Share on other sites

On 4/4/2023 at 6:38 PM, Wesser said:

You are supposed to pass a CVehicle pointer and then pop a floating-point value from the stack using POP_FLOAT (2793) command.

Thank you !
 

0A97: 20@ = vehicle 1@ struct
0AA6: call_method 0x6D3D10 struct 20@ num_params 0 pop 0
0AE9: pop_float 25@

Odd thing is that when the magnet is at highest (closest to heli) position - it shows  0.84. When the rope is fully extended (longest) - it shows 0.01. Anyways - it works. That's almost enough. Time to figure out how to set rope lenght. )
Update. Setting the rope:

 

18@ = 0.01
0AA6: call_method 0x6D3D30 struct 20@ num_params 1 pop 0 18@ //006D3D30 ; int __thiscall CVehicle::SetRopeHeightForHeli(void *this, float)


About the lenght - 0.84 is 'usual' magnet appearance at takeoff (slightly extacted rope). If it is set to 0.99 it is right below the heli. 

Edited by vladvo
Solved
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.