FIX COMPLETO: Jewel Bank + Post Item + Prevención de Auto-Equip (Base Pike 4.3) - Source Mu - Mu Server Files
 

FIX COMPLETO: Jewel Bank + Post Item + Prevención de Auto-Equip (Base Pike 4.3)

Publicado por Dakosmu, Nov 04, 2025, 01:59 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Dakosmu

🛡� FIX COMPLETO: Jewel Bank + Post Item + Prevención de Auto-Equip (PVP/CTRL) (Base Pike 4.3)

Este código es un FIX completo para la Base Pike 4.3 que corrige un problema crítico: el auto-equipamiento involuntario de ítems (como alas o sets) cuando el jugador intenta usar la función Post Item (publicar en chat) o cuando se está en modo PVP (CTRL presionado).

La solución se divide en la modificación de tres archivos clave del Cliente Source:

1. 🛑 ItemMove.cpp: Bloquear Auto-Equip con CTRL

Este cambio es crucial para evitar que el ítem se equipe automáticamente si el jugador está presionando la tecla CTRL (usualmente asociado al modo PK/PVP, o en este caso, al Post Item).

CÓDIGO A USAR EN ItemMove.cpp (Inicio de la función RightClickMoveItem):
void RightClickMoveItem()
{
    // ============================================================
    // ✅ FIX: Block auto-wear if CTRL is pressed (PK mode)
    // ============================================================
    if (GetKeyState(VK_CONTROL) & 0x8000)
    {
        return; // Do NOT auto-equip the item
    }

    // ============================================================
    // ✅ ORIGINAL RIGHT-CLICK LOGIC
    // ============================================================
// ... (resto de la función)
Explicación: La línea `if (GetKeyState(VK_CONTROL) & 0x8000)` verifica si la tecla CTRL está siendo presionada. Si lo está, la función termina inmediatamente (`return;`), bloqueando la lógica de movimiento de ítem y, por ende, el auto-equipamiento.

2. 🏦 CustomJewelBank.cpp: Activación de Jewel Bank con SHIFT

La función Jewel Bank ahora requiere la combinación SHIFT + Clic Derecho para ser ejecutada, liberando el Clic Derecho simple para otras funciones.

CÓDIGO A USAR EN CustomJewelBank.cpp (Función InvetoryItemOver):
void InvetoryItemOver(int This)
{
    lpItemObj item = (lpItemObj) * (DWORD*)(This + 84);

    if (item)
    {
        // Requiere SHIFT + Clic Derecho
        if (GetKeyState(VK_RBUTTON) & 0x8000 && GetKeyState(VK_SHIFT) & 0x8000)
        {
            int start = 12;
            // ... (lógica de cálculo de slot) ...
            int Slot = item->PosX + (item->PosY * 8) + start;

            gCustomJewelBank.JewelBankSend(Slot);
        }
    }

    ((void(__thiscall*)(int))0x007DCF20)(This);
}

void CCustomJewelBank::Load()
{
    //SetCompleteHook(0xE8, 0x007DD0D9, &InvetoryItemOver);
}
Cambio Clave: Se añadió `&& GetKeyState(VK_SHIFT) & 0x8000` a la condición para activar la función.

3. 📢 post_item.cpp: Lógica de Interceptación (CTRL y SHIFT)

Este archivo maneja la lógica central de la interacción, priorizando las nuevas funciones.

CÓDIGO A USAR EN post_item.cpp (Función HookRenderItemToolTip):
void HookRenderItemToolTip(int a1)
{
    ((void(__cdecl*)()) 0x007DCF20)();
    lpItemObj item = (lpItemObj) * (DWORD*)(a1 + 84);
    //===Fix Move Item

    //===
    if (gInterface.CheckWindow(8))
    {
        return;
    }
    DWORD uniqId = 0;
    if (item) {
// ... (cálculo de uniqId) ...
        //
        // CTRL + Right Click (block equip / block move)
        if ((GetKeyState(VK_RBUTTON) & 0x8000) && (GetKeyState(VK_CONTROL) & 0x8000))
        {
            JCItemPublic.PostItemProc(uniqId); // your link item function
            return; // IMPORTANT: block default MU behavior
        }

        else
        {
            // === Right click = Jewel Bank (Ahora con SHIFT) ===
            if (GetKeyState(VK_RBUTTON) & 0x8000 && GetKeyState(VK_SHIFT) & 0x8000)
            {
                // panel: normal / expanded / 2nd inventory
                int panel = *(DWORD*)(a1 + 44);


                if (panel == 200 || panel == 44 || panel == 131)
                {
                    int start = (panel == 200) ? 12 : (panel == 44) ? 76 : 108;
                    int Slot = item->PosX + (item->PosY * 8) + start;

                    gCustomJewelBank.JewelBankSend(Slot);
                    return;
                }
            }
            // === Default Right click = move / equip etc (sin CTRL ni SHIFT) ===
            if (!pIsKeyRepeat(VK_CONTROL))
            {
                JCItemPublic.CDActionItem(item);
                return;
            }
        }
    }
}

Resumen de la Lógica Final:
  • Post Item: CTRL + Clic Derecho. (Bloqueado en `ItemMove.cpp` para evitar auto-equipamiento.)
  • Jewel Bank: SHIFT + Clic Derecho.
  • Equipar/Mover por Defecto: Clic Derecho solo (si no se presiona CTRL ni SHIFT).

🎉 Créditos y Funcionamiento

Este FIX ha sido probado y se confirma su funcionamiento sin errores conocidos.


Este FIX evita que las alas se auto-equipen al intentar hacer Post Item con CTRL.

Descarga de la Base Pike 4.3 (Referencia):
Regístrate para ver el enlace

Créditos:
Código Base: MUCommunity / Tuservermu.
Análisis y Explicación: Gemini / ChatGpt
Bon Dia

Dakosmu

ItemMove.cpp

void RightClickMoveItem()
{
// ============================================================
// ✅ FIX: Block auto-wear if CTRL is pressed (PK mode)
// ============================================================
if (GetKeyState(VK_CONTROL) & 0x8000)
{
return; // Do NOT auto-equip the item
}

// ============================================================
// ✅ ORIGINAL RIGHT-CLICK LOGIC
// ============================================================

if (!ppMousePress(VK_RBUTTON) || PickedItem || ItemMove)
{
return;
}

if (pCheckWindow(pWindowThis(), 9) == 0 && pCheckWindow(pWindowThis(), 13) == 0) // ChaosBox ~ Inventory
{
return;
}

ItemMove = false;
SourceFlag = -1;

SourceSlot = *(DWORD*)((DWORD)InventoryThis(pWindowThis()) + 284);
TargetSlot = -1;

if (SourceSlot >= 0 && SourceSlot < INVENTORY_WEAR_SIZE)
{
if (*(DWORD*)MAIN_CURRENT_MAP == 10 || *(DWORD*)MAIN_CURRENT_MAP == 39)
{
if (SourceSlot == 7 &&
GetItemEquipedIndex(8) != GET_ITEM(13, 3) &&
GetItemEquipedIndex(8) != GET_ITEM(13, 4) &&
GetItemEquipedIndex(8) != GET_ITEM(13, 37))
{
return;
}

if (SourceSlot == 8 &&
(GetItemEquipedIndex(8) == GET_ITEM(13, 3) ||
GetItemEquipedIndex(8) == GET_ITEM(13, 4) ||
GetItemEquipedIndex(8) == GET_ITEM(13, 37)) &&
GetItemEquipedIndex(7) == 0xFFFF)
{
return;
}
}

DWORD ItemStruct = GetItemEquiped(SourceSlot);

if (ItemStruct && GetItemEquipedIndex(SourceSlot) != 0xFFFF)
{
ITEM_INFO2* lpItemInfo = GetItemInfo(*(WORD*)ItemStruct);

TargetSlot = InventoryFindEmptySlot(InventoryThis(pWindowThis()), lpItemInfo->Width, lpItemInfo->Height);

if (TargetSlot != -1)
{
SendRequestEquipmentItem(0, SourceSlot, ItemStruct, 0, INVENTORY_WEAR_SIZE + TargetSlot);
ResetMouseRButton();
ItemMove = true;
SourceFlag = 0;
}
}
}
else
{
int InventoryMain = InventoryFindItemSlot(GetMyInventoryCtrl(InventoryThis(pWindowThis()), 0), pCursorX, pCursorY);
int InventoryExpand1 = InventoryFindItemSlot(GetMyInventoryCtrl(InventoryThis(pWindowThis()), 1), pCursorX, pCursorY);
int InventoryExpand2 = InventoryFindItemSlot(GetMyInventoryCtrl(InventoryThis(pWindowThis()), 2), pCursorX, pCursorY);

if (pCheckWindow(pWindowThis(), 9) != 0)
{
DWORD MixItemStruct = (DWORD)InventoryFindItem(MixGetMyInventoryCtrl(MixInventoryThis(pWindowThis())), pCursorX, pCursorY);

if (MixItemStruct)
{
ITEM_INFO2* lpItemInfo = GetItemInfo(*(WORD*)MixItemStruct);

SourceSlot = InventoryFindItemSlot(MixGetMyInventoryCtrl(MixInventoryThis(pWindowThis())), pCursorX, pCursorY);
TargetSlot = InventoryFindEmptySlot(InventoryThis(pWindowThis()), lpItemInfo->Width, lpItemInfo->Height);

if (SourceSlot != -1 && TargetSlot != -1)
{
SendRequestEquipmentItem(3, SourceSlot, MixItemStruct, 0, INVENTORY_WEAR_SIZE + TargetSlot);
ResetMouseRButton();
ItemMove = true;
SourceFlag = 1;
}
}
else
{
DWORD InventoryCtrl = -1;

DWORD ItemStruct = (DWORD)InventoryFindItemAtPt(InventoryThis(pWindowThis()), pCursorX, pCursorY, &InventoryCtrl);

if (ItemStruct)
{
ITEM_INFO2* lpItemInfo = GetItemInfo(*(WORD*)ItemStruct);

if (InventoryMain != -1)
SourceSlot = INVENTORY_WEAR_SIZE + InventoryMain;
else if (InventoryExpand1 != -1)
SourceSlot = INVENTORY_EXT1_SIZE + InventoryExpand1;
else if (InventoryExpand2 != -1)
SourceSlot = INVENTORY_EXT2_SIZE + InventoryExpand2;

TargetSlot = InventoryMixFindEmptySlot(MixGetMyInventoryCtrl(MixInventoryThis(pWindowThis())), lpItemInfo->Width, lpItemInfo->Height);

if (SourceSlot != -1 && TargetSlot != -1)
{
SendRequestEquipmentItem(0, SourceSlot, ItemStruct, 3, TargetSlot);
ResetMouseRButton();
ItemMove = true;
SourceFlag = 0;
}
}
}
}
else
{
if (pCheckWindow(pWindowThis(), 7) != 0 || pCheckWindow(pWindowThis(), 8) != 0) // Trade ~ Warehouse
{
return;
}

DWORD InventoryCtrl = -1;

DWORD ItemStruct = (DWORD)InventoryFindItemAtPt(InventoryThis(pWindowThis()), pCursorX, pCursorY, &InventoryCtrl);

if (ItemStruct)
{
if (InventoryMain != -1)
SourceSlot = INVENTORY_WEAR_SIZE + InventoryMain;
else if (InventoryExpand1 != -1)
SourceSlot = INVENTORY_EXT1_SIZE + InventoryExpand1;
else if (InventoryExpand2 != -1)
SourceSlot = INVENTORY_EXT2_SIZE + InventoryExpand2;

TargetSlot = GetInventoryWearSlot(*(WORD*)ItemStruct);

if (SourceSlot != -1 && TargetSlot != 0xFF)
{
SendRequestEquipmentItem(0, SourceSlot, ItemStruct, 0, TargetSlot);
ResetMouseRButton();
ItemMove = true;
SourceFlag = 0;
}
}
}
}
}

CustomJewelBank.cpp

void InvetoryItemOver(int This)
{
lpItemObj item = (lpItemObj) * (DWORD*)(This + 84);

if (item)
{
if (GetKeyState(VK_RBUTTON) & 0x8000 && GetKeyState(VK_SHIFT) & 0x8000)
{
int start = 12;
if (*(DWORD*)(This + 44) == 200)
{
start = 12;
}
else if (*(DWORD*)(This + 44) == 44)
{
start = 76;
}
else if (*(DWORD*)(This + 44) == 131)
{
start = 108;
}

int Slot = item->PosX + (item->PosY * 8) + start;

gCustomJewelBank.JewelBankSend(Slot);
}
}

((void(__thiscall*)(int))0x007DCF20)(This);
}

void CCustomJewelBank::Load()
{
//SetCompleteHook(0xE8, 0x007DD0D9, &InvetoryItemOver);
}


post_item.cpp


void HookRenderItemToolTip(int a1)
{
((void(__cdecl*)()) 0x007DCF20)();
lpItemObj item = (lpItemObj) * (DWORD*)(a1 + 84);
//===Fix Move Item

//===
if (gInterface.CheckWindow(8))
{
return;
}
DWORD uniqId = 0;
if (item) {
int pos = -1;
if (a1 == *(DWORD*)(*(DWORD*)0x098670B8 + 0x18))
{
uniqId = item->UniqueID;
}
else if (a1 == *(DWORD*)(*(DWORD*)0x098670B8 + 0x1C))
{
uniqId = item->UniqueID + 0x10000000;
}
else if (a1 == *(DWORD*)(*(DWORD*)0x098670B8 + 0x20))
{
uniqId = item->UniqueID + 0x20000000;
}
//
// CTRL + Right Click (block equip / block move)
if ((GetKeyState(VK_RBUTTON) & 0x8000) && (GetKeyState(VK_CONTROL) & 0x8000))
{
JCItemPublic.PostItemProc(uniqId); // your link item function
return; // IMPORTANT: block default MU behavior
}

else
{
// === Right click = Jewel Bank ===
if (GetKeyState(VK_RBUTTON) & 0x8000 && GetKeyState(VK_SHIFT) & 0x8000)
{
// panel: normal / expanded / 2nd inventory
int panel = *(DWORD*)(a1 + 44);


if (panel == 200 || panel == 44 || panel == 131)
{
int start = (panel == 200) ? 12 : (panel == 44) ? 76 : 108;
int Slot = item->PosX + (item->PosY * 8) + start;

gCustomJewelBank.JewelBankSend(Slot);
return;
}
}
// === Default Right click = move / equip etc ===
if (!pIsKeyRepeat(VK_CONTROL))
{
JCItemPublic.CDActionItem(item);
return;
}
}
}
}

Bon Dia

🡱 🡳
Real Time Web Analytics