[G2NK] Pobieranie instancji namierzonego przedmiotu z ekwipunku - c.d. 1310 3

O temacie

Autor Khantor

Zaczęty 7.11.2020 roku

Wyświetleń 1310

Odpowiedzi 3

Khantor

Khantor

Użytkownicy
posty53
Propsy12
Profesjabrak
  • Użytkownicy
Witam. Jak chcę sobie powyciągać zmienne namierzonego przedmiotu w ekwipunku no to używam

container = ECX;

const int call = 0;

if (CALL_Begin(call))
{
CALL_PutRetValTo(_@(selectedItemPtr));
CALL__thiscall(_@(container), 7377600);
call = CALL_End();
};

itm = _^(selectedItemPtr);

i hookuje to na

HookEngineF(7370416, 6, nazwa_funkcji);

Działa to na otwartym ekwipunku. A może ktoś powiedzieć takiemu laikowi jak ja co mam zrobić, żeby móc wyciągnąć zmienne namierzonego itemu ale w polu ekwipunku otwartej skrzyni, polu ekwipunku handlarza podczas handlu i polu ekwipunka przeszukiwanego npc? Byłbym wdzięczny i postawiłbym kratę piwa w zamian ale zaraza i nie wolno.
 

Siemekk

Siemekk

Złote Wrota
Untersturmfuhrer
posty2147
Propsy1147
ProfesjaProgramista
  • Złote Wrota
  • Untersturmfuhrer
To są różne typy kontenera, musisz poszukać adresów dla wszystkich tych metod (są wirtualne).
 

Patrix9999

Patrix9999

Użytkownicy
posty127
Propsy37
Profesjabrak
  • Użytkownicy
Skoro są wirtualne, to może by wykorzystać vtable do wykonania member function?
 

Khantor

Khantor

Użytkownicy
posty53
Propsy12
Profesjabrak
  • Użytkownicy
No dobra, jakby ktoś takiego bajeru kiedyś potrzebował to podaje rozwiązanie:

func void FocusItemInTradeWIndow_Init()
{
    HookEngineF(7370416, 6, FocusItemInTradeWIndowAndMore);
};

func int oCItemContainer_GetSelectedItem(var int containerPtr)
{   
    const int call = 0;
    if (CALL_Begin(call))
{
        CALL_PutRetValTo(_@(ret));
        CALL__thiscall(_@(containerPtr), 7377600);
        call = CALL_End();
    };

    var int ret;
    return +ret;
};

func int oCItemContainer_GetNextContainerLeft(var int containerPtr, var int currentPtr)
{
    const int call = 0;
    if (CALL_Begin(call))
{
        CALL_PutRetValTo(_@(ret));
        CALL_PtrParam(_@(currentPtr));
        CALL__thiscall(_@(containerPtr), 7359424);
        call = CALL_End();
    };

    var int ret;
    return +ret;
};

func int IsPlayerContainerSelected()
{
her = MEM_CpyInst(hero);

    return her.inventory2_oCItemContainer_frame != 0;
};

func void FocusItemInTradeWIndowAndMore()
{
her = MEM_CpyInst(hero);
//var C_ITEM  citm;
var oCItem oItm;
var int itemPtr;
var int contLeft;

if (IsPlayerContainerSelected() == 0)
{
contLeft = oCItemContainer_GetNextContainerLeft(_@(her.inventory2_vtbl), _@(her.inventory2_vtbl));
if (contLeft)
{
itemPtr = oCItemContainer_GetSelectedItem(contLeft);
};
}
else if (IsPlayerContainerSelected() == 1)
{
if (ECX != contLeft)
{
itemPtr = oCItemContainer_GetSelectedItem(ECX);
};
};

if (itemPtr)
{
//citm = _^(itemPtr);
oItm = _^(itemPtr);
};
};

Jak ktoś dodatkowo jest zainteresowany, żeby funkcja działała tylko przy konkretnym otworzeniu ekwipunku to może dołożyć warunki:

1) Tylko ręczne otworzenie ekwipunku:
Patrz punkt 2 (żeby wiedzieć skąd dostać "InventoryIsOpenWithMode(5)") oraz:

https://themodders.org/index.php?topic=30411.0
Przy czym do ostatniej funkcji podopisywałem parę warunków, żeby na pewno się wywoływała tylko przy ręcznym otworzeniu:

func void Is_Inventory_Opened_Manually()
{
KeyInventory1 = ReadKeyFromIni ("keyInventory", 1);
KeyInventory2 = ReadKeyFromIni ("keyInventory", 2);

if (IsInventoryOpenedManually == 1)
{
her = Hlp_GetNpc(hero);
inv = _@(her.inventory2_vtbl);

const int call = 0;
if (CALL_Begin(call))
{
CALL_PutRetValTo(_@(ret_InventoryIsOpen));
CALL__thiscall(_@(inv), 7377408);
call = CALL_End();
};

if (ret_InventoryIsOpen == 0)
{
IsInventoryOpenedManually = 0;
};
};

if ((Npc_GetBodyState(hero) == BS_INVENTORY)
&& (InventoryIsOpenWithMode(5) == 0)
&& (IsInventoryKeyPressed == 1))
{
IsInventoryOpenedManually = 1;
};

IsInventoryKeyPressed = 0;

if (((MEM_KeyState(KeyInventory1) == KEY_PRESSED)
|| (MEM_KeyState(KeyInventory2) == KEY_PRESSED))
&& ((Npc_GetBodyState(hero) == BS_STAND)
|| (Npc_GetBodyState(hero) == BS_RUN)
|| (Npc_GetBodyState(hero) ==  BS_FALL))
&& (hero.aivar[AIV_INVINCIBLE] == FALSE))
{
IsInventoryKeyPressed = 1;
};
};

2) Tylko podczas handlu:
func int InventoryIsOpen()
{
    var oCNpc her; her = Hlp_GetNpc(hero);
    var int inv; inv = _@(her.inventory2_vtbl);
    var int ret;
    const int call = 0;

    if (CALL_Begin(call))
{
        CALL_PutRetValTo(_@(ret));
        CALL__thiscall(_@(inv), 7377408);
        call = CALL_End();
    };

    return +ret;
};

func int GetInventoryMode()
{
    var oCNpc her; her = Hlp_GetNpc(hero);
    var int inv; inv = _@(her.inventory2_vtbl);
    var int ret;
    const int call = 0;

    if (CALL_Begin(call))
{
        CALL_PutRetValTo(_@(ret));
        CALL__thiscall(_@(inv), 7360672);
        call = CALL_End();
    };

    return +ret;
};

//INV_MODE_DEFAULT = 0
//INV_MODE_CONTAINER = 1
//INV_MODE_PLUNDER = 2
//INV_MODE_STEAL = 3
//INV_MODE_BUY = 4
//INV_MODE_SELL = 5 !!!!!!!!
//INV_MODE_MAX = 6

func int InventoryIsOpenWithMode(var int mode)
{
    return InventoryIsOpen() && GetInventoryMode() == mode;
};

if (InventoryIsOpenWithMode(5) == 1) // <- to jest warunek jakby co

3) Tylko podczas przeszukiwania NPC:
Patrz punkt 2 oraz:
var c_npc trgt;

if ((IsInventoryOpenedManually == 0)// <- to jest warunek jakby co
&& (InventoryIsOpenWithMode(5) == 0)// <- to jest warunek jakby co
&& (Hlp_GetInstanceID(trgt))// <- to jest warunek jakby co
&& (Hlp_Is_oCNpc(her.focus_vob)))// <- to jest warunek jakby co

4) Tylko podczas przeszukiwania skrzyń:
Patrz punkt 2 oraz:
var c_npc trgt;

if ((IsInventoryOpenedManually == 0)// <- to jest warunek jakby co
&& (InventoryIsOpenWithMode(5) == 0)// <- to jest warunek jakby co
&& (Hlp_Is_oCNpc(her.focus_vob) == 0))// <- to jest warunek jakby co
 


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry