- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 445
- Реакции
- 10
Народ, кто плотно ковыряет CryEngine в Warface, держите базу по структурам инвентаря. Если пилите что-то сложнее обычного ЕСП и нужно адекватно обрабатывать Dual-wield (когда две пушки в руках), то стандартных методов может не хватить.
Суть в том, чтобы вытащить указатель на второе оружие (левая рука) через текущий айтем в правой руке. Ниже привожу разбор классов с актуальными оффсетами и логику получения sub-weapon.
Структура инвентаря и основные оффсеты
Логика получения айтема
Для корректной работы нужно искать айтем по имени класса сущности. В CryAction это делается через проход по слотам инвентаря. Если просто пастите — убедитесь, что ваш GetEntity отрабатывает корректно.
Связка WeaponGeneral и Settings
Чтобы понять, есть ли в левой руке что-то еще, прыгаем в CWeaponSettings. Оффсет на m_subWeapon сидит довольно глубоко в базе настроек.
Пример использования в коде
Метод рабочий, юзаю в своем интернале для правильного просчета визуала и аима при стрельбе с двух рук. Единственный нюанс — чекайте сигнатуры, в последних обновах MRAC мог немного подвигать структуры, но оффсеты выше пока актуальны.
Кто-нибудь пробовал через это реализовать кастомный скинчейнджер на обе пушки в акимбо?
Суть в том, чтобы вытащить указатель на второе оружие (левая рука) через текущий айтем в правой руке. Ниже привожу разбор классов с актуальными оффсетами и логику получения sub-weapon.
Структура инвентаря и основные оффсеты
Код:
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 отрабатывает корректно.
Код:
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 сидит довольно глубоко в базе настроек.
- CItem -> m_weaponExt (0x0038)
- CWeaponGeneral -> m_settings (0x0048)
- CBaseSettings -> m_subWeapon (0x0A18) — тут лежит CryString с названием пушки для левой руки.
Пример использования в коде
Код:
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 мог немного подвигать структуры, но оффсеты выше пока актуальны.
Кто-нибудь пробовал через это реализовать кастомный скинчейнджер на обе пушки в акимбо?