vladvo Posted March 31 Share Posted March 31 (edited) 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 4 hours ago by vladvo Link to comment Share on other sites More sharing options...
Jack Posted Monday at 01:25 PM Share Posted Monday at 01:25 PM (edited) @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 [email protected] = 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 [email protected] = 0 to 7 step 1 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration [email protected] result_to [email protected] // CEntity *m_pRopeHolder; if [email protected] <> 0 then // there's an entity attached at one or more ropes end end :readMemoryOffsetWithIterr // [email protected] CRopeStruct; [email protected] offset; [email protected] iteration [email protected] *= 0x328 // CRope struc size 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 005A: [email protected] += [email protected] 005A: [email protected] += [email protected] 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 0AB2: cleo_return 1 [email protected] Now lets check if that rope has our magnet: Spoiler for [email protected] = 0 to 7 step 1 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration [email protected] result_to [email protected] // CEntity *m_pRopeHolder; 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x314 iteration [email protected] result_to [email protected] // CObject *m_pRopeAttachObject; if and [email protected] <> 0 [email protected] <> 0 then [email protected] += 0x22 0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 0 // CEntity *m_nModelIndex; [email protected] += 0x22 0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 0 // CEntity *m_nModelIndex; if and [email protected] == #LEVIATHN [email protected] == 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 // [email protected] CRopeStruct; [email protected] offset; [email protected] iteration [email protected] *= 0x328 // CRope struc size 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 005A: [email protected] += [email protected] 005A: [email protected] += [email protected] 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 0AB2: cleo_return 1 [email protected] and now we can check its lenght: Spoiler const INDUS_MAGNET = 3053 CRopeStruct = 0x556AE2 // pointer to _ZN6CRopes6aRopesE end while true wait 0 for [email protected] = 0 to 7 step 1 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x310 iteration [email protected] result_to [email protected] // CEntity *m_pRopeHolder; 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x314 iteration [email protected] result_to [email protected] // CObject *m_pRopeAttachObject; if and [email protected] <> 0 [email protected] <> 0 then [email protected] += 0x22 0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 0 // CEntity *m_nModelIndex; [email protected] += 0x22 0A8D: [email protected] = read_memory [email protected] size 2 virtual_protect 0 // CEntity *m_nModelIndex; if and [email protected] == #LEVIATHN [email protected] == INDUS_MAGNET then 0085: [email protected] = [email protected] 0AB1: cleo_call @readMemoryOffsetWithIterr params 3 stuct CRopeStruct offset 0x31C iteration [email protected] result_to [email protected] // float m_fRopeSegmentLength; 0087: [email protected] = [email protected] [email protected] *= 10.0 0092: [email protected] = float_to_integer [email protected] 03F0: enable_text_draw 1 045A: text_draw_1number 50.0 100.0 'NUMBER' [email protected] // 8 - 0 where 8 is the shortest rope value which is odd end end end end :readMemoryOffsetWithIterr // [email protected] CRopeStruct; [email protected] offset; [email protected] iteration [email protected] *= 0x328 // CRope struc size 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 005A: [email protected] += [email protected] 005A: [email protected] += [email protected] 0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0 0AB2: cleo_return 1 [email protected] 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 Tuesday at 04:12 PM by Jack Wanted Level Editor Gore Level Effect [III] My YouTube Channel Link to comment Share on other sites More sharing options...
Wesser Posted Tuesday at 03:38 PM Share Posted Tuesday at 03:38 PM You are supposed to pass a CVehicle pointer and then pop a floating-point value from the stack using POP_FLOAT (2793) command. vladvo and Jack 2 012 345 678 9A BCD EFG HIJK LMN OPQR STUV WX YZ Link to comment Share on other sites More sharing options...
ArmanCan Posted 10 hours ago Share Posted 10 hours ago @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 More sharing options...
vladvo Posted 5 hours ago Author Share Posted 5 hours ago 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 More sharing options...
vladvo Posted 4 hours ago Author Share Posted 4 hours ago (edited) 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: [email protected] = vehicle [email protected] struct 0AA6: call_method 0x6D3D10 struct [email protected] num_params 0 pop 0 0AE9: pop_float [email protected] 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: [email protected] = 0.01 0AA6: call_method 0x6D3D30 struct [email protected] num_params 1 pop 0 [email protected] //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 3 hours ago by vladvo Solved Link to comment Share on other sites More sharing options...