Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Исходник [Сурс] Warface — Получение sub-weapon (левая рука) при Dual-wield

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
445
Реакции
10
Народ, кто плотно ковыряет CryEngine в Warface, держите базу по структурам инвентаря. Если пилите что-то сложнее обычного ЕСП и нужно адекватно обрабатывать Dual-wield (когда две пушки в руках), то стандартных методов может не хватить.

Суть в том, чтобы вытащить указатель на второе оружие (левая рука) через текущий айтем в правой руке. Ниже привожу разбор классов с актуальными оффсетами и логику получения sub-weapon.

Структура инвентаря и основные оффсеты
Код:
Expand Collapse Copy
class CActor : public IActor, CPlayer, IGameObjectExtension {
    CInventory* m_pInventory; // 0x0038
};

using EntityId = uint32;

struct SInventoryStats {
    TInventoryVector slots;    // 0x0000
    char pad_0018[24];         // 0x0018
    TAmmoInfoMap ammoInfo;     // 0x0030
    char pad_0040[56];         // 0x0040
    TAmmoInfoIt ammoIterator;  // 0x0078
    char pad_0080[8];          // 0x0080
    EntityId currentItemId;    // 0x0088
    EntityId holsteredItemId;  // 0x008C
    EntityId lastItemId;       // 0x0090
};

class CInventory : public IInventory, IGameObjectExtension {
    // ... методы GetItemByName и GetCurrentItemId
    SInventoryStats m_stats;   // 0x0028 (AOB check: 85 D2 ? ? 48 8B 41 ?)
};

Логика получения айтема
Для корректной работы нужно искать айтем по имени класса сущности. В CryAction это делается через проход по слотам инвентаря. Если просто пастите — убедитесь, что ваш GetEntity отрабатывает корректно.

Код:
Expand Collapse Copy
CItem* CInventory::GetItemByName(const char* name) const {
    if (!name) return nullptr;
    for (auto it = m_stats.slots.begin(); it != m_stats.slots.end(); ++it) {
        if (auto pEntity = CryENGINE::GetCryAction()->GetEntitySystem()->GetEntity(*it)) {
            if (!__strcmpi(pEntity->m_pClass->m_sName.c_str(), name))
                return CryENGINE::GetCryAction()->GetItemSystem()->GetItem(pEntity->GetId());
        }
    }
    return nullptr;
}

Связка WeaponGeneral и Settings
Чтобы понять, есть ли в левой руке что-то еще, прыгаем в CWeaponSettings. Оффсет на m_subWeapon сидит довольно глубоко в базе настроек.
  1. CItem -> m_weaponExt (0x0038)
  2. CWeaponGeneral -> m_settings (0x0048)
  3. CBaseSettings -> m_subWeapon (0x0A18) — тут лежит CryString с названием пушки для левой руки.

Пример использования в коде
Код:
Expand Collapse Copy
if (auto pInventory = pClientActor->m_pInventory) {
    if (auto pCurrItem = pItemSystem->GetItem(pInventory->GetCurrentItemId())) {
        // pCurrItem — это наша правая рука
        auto pWeaponExtR = pCurrItem->m_weaponExt;
        if (!pWeaponExtR || !pWeaponExtR->m_settings) return;

        auto subWeapon = pWeaponExtR->m_settings->m_subWeapon;
        if (subWeapon.empty()) return; // Обычный режим, второй пушки нет

        if (auto pSubItem = pInventory->GetItemByName(subWeapon.c_str())) {
            // pSubItem — профит, получили указатель на левую руку
        }
    }
}

Метод рабочий, юзаю в своем интернале для правильного просчета визуала и аима при стрельбе с двух рук. Единственный нюанс — чекайте сигнатуры, в последних обновах MRAC мог немного подвигать структуры, но оффсеты выше пока актуальны.

Кто-нибудь пробовал через это реализовать кастомный скинчейнджер на обе пушки в акимбо?
 
дрочит левая рука дрочит правая рука
Пример использования в коде
if (auto pInventory = pClientActor->m_pInventory) { if (auto pCurrItem = pItemSystem->GetItem(pInventory->GetCurrentItemId())) { // pCurrItem — это наша правая рука auto pWeaponExtR = pCurrItem->m_weaponExt; if (!pWeaponExtR || !pWeaponExtR->m_settings) return; auto subWeapon = pWeaponExtR->m_settings->m_subWeapon; if (subWeapon.empty()) return; // Обычный режим, второй пушки нет if (auto pSubItem = pInventory->GetItemByName(subWeapon.c_str())) { // pSubItem — профит, получили указатель на левую руку } } }
 
Назад
Сверху Снизу