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

Вопрос Крипы в дедлоке

Imgui Seller
Дизайнер
Дизайнер
Статус
Оффлайн
Регистрация
26 Авг 2023
Сообщения
805
Реакции
118
Как делать проверку что сущность крип?
Вальвы там херни какой-то наделали у крипов в катках нет designer name и команда какая-то супер большая и странная
 
Здарова. Вальвы ничего не ломали, просто в Source 2 (и конкретно в Deadlock) у нейтралок специфическая иерархия. Скорее всего, ты пытаешься прочитать имя из контроллера или обращаешься к базовому классу игрока, а у крипов эта структура работает иначе.

Команду (TeamNum) у лесных мобов чекать вообще нет смысла — там действительно будет лежать мусор или огромные значения, потому что это нейтральные объекты вне привычных команд игрока.

Вот как я реализовал это в своем экстернале (код на AHK, но логика 1 в 1 переносится на C++ / C#). Вся суть — читать NamePtr из IdentityAddress по смещению 0x20.

Как это работает под капотом:​

  1. Лупим Entity List: Идем по чанкам списка сущностей (по 512 штук), чтобы не жрать процессорное время впустую.
  2. Достаем Identity: Получаем базовый адрес ивента: IdentityAddress = Base + 0x70 * (mobIndex & 0x1FF).
  3. Читаем поинтер на имя: Берем NamePtr строго по смещению + 0x20 от IdentityAddress.
  4. Парсим стрингу: Читаем строку (хватит 48 байт) и фильтруем через обычный поиск подстроки (InStr).
Искомые имена:
  • Для обычных лесных крипов (кемпов): ищем npc_trooper_neutral
  • Для автоматов (грешников) с душами: ищем npc_neutral_sinners_sacrifice
  • Для рун: ищем item_xp_rune

Быстрый чеклист по оффсетам мобов:​

  • Имя (Designer Name): IdentityAddress + 0x20
  • Здоровье (HP): EntityPtr + 0x354 (читаем обычный int. Если <= 0 — крип мертв, скипаем отрисовку).
  • Спящий режим (Dormant): Читается из GameSceneNode + offsets.m_bDormant. Помогает не рендерить мобов, которые находятся вне зоны видимости сервера или неактивны.
Сам кусок логики для наглядности:

Код:
Expand Collapse Copy
IdentityAddress := currentAddressBase + 0x70 * (mobIndex & 0x1FF)
EntityPtr := 1337flex.Read(IdentityAddress + 0x0, "Int64")

if (EntityPtr) {
    NamePtr := 1337flex.Read(IdentityAddress + 0x20, "Int64") ; Вот тут лежит имя!
    if (NamePtr) {
        sName := ReadString(NamePtr, 48)
        
        ; Фильтруем крипов
        if (InStr(sName, "npc_trooper_neutral"))
            type := "camp"
        else if (InStr(sName, "npc_neutral_sinners_sacrifice") || InStr(sName, "item_xp_rune"))
            type := "sinner"
            
        ; Если нашли - закидываем в массив для рендера
    }
}

Никакой магии, просто правильный оффсет ивента. Прикручивай кэширование стрингов по поинтерам, чтобы не дергать память каждый кадр, и всё будет летать.
 
а, тебе именно крипы обычные, а не кемпы или SS, неправильно прочитал чёт, сорян

такого у меня в чите нету, только души
поэтому сверху инфа наверное тебе не поможет никак
 
пробуй так:
Expand Collapse Copy
auto C_BaseEntity::IsNpcTrooper() -> bool
{
    const auto* pszDesingerName = pEntityIdentity()->DesingerName().String();

    if ( pszDesingerName && strcmp( pszDesingerName , XorStr( "npc_trooper" ) ) == 0 )
        return true;

    return false;
}

auto C_BaseEntity::IsNpcTrooperNeutral() -> bool
{
    const auto* pszDesingerName = pEntityIdentity()->DesingerName().String();

    if ( pszDesingerName && strcmp( pszDesingerName , XorStr( "npc_trooper_neutral" ) ) == 0 )
        return true;

    return false;
}
 
В настоящих катках у entity list просто огромный размер и крипы находятся на индексах дальше 2-3к, возможно ты итерируешься по списку до них
 
В настоящих катках у entity list просто огромный размер и крипы находятся на индексах дальше 2-3к, возможно ты итерируешься по списку до них
реально, респект тебе
нахуй они ваще крипов за 512 индекс выкинули
 
Назад
Сверху Снизу