HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- Нубские вопросы от <censored> и других нубов (https://hlfx.ru/forum/showthread.php?threadid=4535)
Отправлено Ku2zoff 07-12-2021 в 17:15:
Цитата:
Chyvachok писал:
модель ХД Барника но с анимациями под автомат-дробовик и с пинком?
Zombie Edition же. За авторством наших ребят. Я оттуда взял анимации дробовика. Правда, переделал ходьбу и бег, т.к. они там ущербные. И добавил turnleft/turnright. Попозже аттачем скину тебе smd файлы, может допилишь, чтобы было красиво. Анимки эти заточены под модели с подвижными глазами, веками и бровями от Ромки или из Decay. Так что работай с этими моделями. Потом можно вкомпилить в обычного HD барника, скелеты совместимы.Цитата:
Chyvachok писал:
нельзя как в БХЛ сделать так чтобы НПС живой оставался, к примеру как зомби с отстреленной рукой, не придумал как, и чтобы оно еще нормально все работало.
Делаешь по аналогии с limp health у грантов: меняешь анимации в SetActivity. То есть по факту монстр жив, но активности у него другие и внешний вид тоже.
Добавлено 08-12-2021 в 00:12:
Я бы не раздувал код TraceAttack, а передавал хитгруппу сразу в функцию SpawnSpecificGib. А там уже switch case.
Добавлено 08-12-2021 в 00:15:
Кстати, такой вопрос. Кто качал Accurate SD models учёных и барников? В основе модели от Ромки, но головы очень похожи на LD версии, нет этих убогих ХДпачных рож. Хотелось бы ещё что-такое найти, чтобы бошки были высокополигональные, но смотрелись олдскульно.
Отправлено Chyvachok 07-12-2021 в 17:34:
Цитата:
Ku2zoff писал:
Я бы не раздувал код TraceAttack, а передавал хитгруппу сразу в функцию SpawnSpecificGib.
А чем это чревато? Я по лучше не придумал, но я честно особо красиво код писать и не умею.
Отправлено Ku2zoff 07-12-2021 в 19:42:
Chyvachok особо ничем, разве что удобочитаемость снижается.
Добавлено 08-12-2021 в 02:42:
Как обещал - секвенции дробовика и пинка хедкраба ногой в аттаче. Надо немножко их допилить. Для M4 секвенции можно выдрать из оригинальной модели мода Zombie Edition.
Отправлено FreeSlave 08-12-2021 в 17:01:
Цитата:
Aynekko писал:
Кстати, пока вчера тестировал двери, обнаружил еще вот что. Есть две двери. Одна залочена мастером и не может быть открыта. Вторая открыта. Обе двери ведут в один и тот же открытый коридор. Ноды везде построены. Я юзаю барника и улетаю ноклипом сквозь дверь с мастером. Итог: барник упирается в дверь с мастером и спамит в консоль "нимагу идти". Вот бы сделать, чтобы этот путь забраковался и он стал искать обходной путь. Что-то вчера копался с этими нодами, но так и не вкурил, как это реализовать.
Да, если строить сквозь все двери, есть такой баг. Я отследил его до CGraph::FindShortestPath. А виновата вот эта строчка: https://github.com/ValveSoftware/ha.../nodes.cpp#L611
Во время построения графа вызывается ComputeStaticRoutingTables, которая по окончании и ставит m_fRoutingComplete в TRUE, и любой FindShortestPath начинает идти по уже проложенному пути, не заходя в другую ветку кода, где вызывается HandleLinkEnt https://github.com/ValveSoftware/ha.../nodes.cpp#L701
Вызывается он кстати с параметром NODEGRAPH_STATIC, что похоже в какой-то мере и есть аналог нашей булевой переменной, которую мы вводим во время CTestHull::BuildNodeGraph.
FindShortestPath вызывается при построения пути по нодам для монстра в CBaseMonster::FGetNodeRoute - https://github.com/ValveSoftware/ha...sters.cpp#L2789
Что приводит к тому, что поиск пути попадает в ветку с m_fRoutingComplete, без учёта энтитей.
Кстати, из-за этого в оригинальной Халфе может затупить монстр в попытках обойти func_breakable - с NODEGRAPH_STATIC для него всегда возвращается TRUE, в результате монстр считает, что может пройти насквозь (как и в твоём случае с дверью).
Лечится это следующим способом.
Меняем сигнатуру FindShortestPath
C++ Source Code:
int FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask ); |
на
C++ Source Code:
int FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask, bool dynamic = false ); |
Заменяем
C++ Source Code:
на
C++ Source Code:
if( !dynamic && m_fRoutingComplete ) |
Заменяем
C++ Source Code:
if( !HandleLinkEnt( iCurrentNode, m_pLinkPool[m_pNodes[iCurrentNode].m_iFirstLink + i].m_pLinkEnt, afCapMask, NODEGRAPH_STATIC ) ) |
на
C++ Source Code:
if( !HandleLinkEnt( iCurrentNode, m_pLinkPool[m_pNodes[iCurrentNode].m_iFirstLink + i].m_pLinkEnt, afCapMask, dynamic ? NODEGRAPH_DYNAMIC : NODEGRAPH_STATIC ) ) |
В FGetNodeRoute вызываем WorldGraph.FindShortestPath с true в качестве нового последнего аргумента.
Что стоит иметь в виду: ветка с m_fRoutingComplete скорее всего больше вообще нигде не будет выполняться. Не знаю, хорошо ли это, и как это скажется на производительности.__________________
I'm on github
I'm on opendesktop.org
Отправлено Aynekko 08-12-2021 в 17:58:
Цитата:
FreeSlave писал:
FindShortestPath
Вот я тоже уперся туда, а дальше залип.
Цитата:
FreeSlave писал:
по окончании и ставит m_fRoutingComplete в TRUE
Ага. Наверное, надо его использовать вместо нового условия, что я воткнул.Цитата:
FreeSlave писал:
Лечится это следующим способом.
Я, конечно, офигел, но это реально работает. Монстряка поумнел на глазах
спасибо большое. Буду тестировать.
Добавлено 08-12-2021 в 20:26:
Цитата:
Aynekko писал:
Буду тестировать.
Работает после построения нод. Перезапустил карту - опять упирается в дверь. Карту перекомпилировал и проверил еще раз, так же. Интересненько
Добавлено 08-12-2021 в 20:58:
Мой косяк. Мой BuildingRoute почему-то после перезапуска карты стал true. Где-то не учел условие. Попробую m_fRoutingComplete.
Да, отлично, можно его использовать. Ноды построились через закрытые двери и после перезапуска тоже все работает.__________________
Мой мод на Xash
Отправлено FreeSlave 08-12-2021 в 18:06:
Цитата:
Aynekko писал:
Мой косяк. Мой BuildingRoute почему-то после перезапуска карты стал true. Где-то не учел условие. Попробую m_fRoutingComplete.
Попробуй всё-таки вынести в глобальную переменную вне класса. У тебя сэйв-рестор графа может быть поломан.
А вообще вполне возможно что дополнительная переменная не нужна и достаточно ориентироваться на NODEGRAPH_STATIC, всегда возвращая TRUE из HandleLinkEnt, вызванной с NODEGRAPH_STATIC, для дверей и func_breakable.__________________
I'm on github
I'm on opendesktop.org
Отправлено Aynekko 08-12-2021 в 18:51:
Цитата:
FreeSlave писал:
У тебя сэйв-рестор графа может быть поломан.
После сейв-рестора у меня вообще HandleLinkEnt перестал вызываться (выставил алерт в самом начале). Если просто загружать карту, с/без графа, то все норм. Свою переменную я вообще вычистил полностью, использовал ту
C++ Source Code:
1 | if ( FClassnameIs( pevLinkEnt, "func_door" ) || FClassnameIs( pevLinkEnt, "func_door_rotating" ) ) |
3 | if( !WorldGraph.m_fRoutingComplete ) |
Добавлено 08-12-2021 в 21:51:
Это условие не проходит после сейврестора, оно null становится
C++ Source Code:
// check the connection from the current node to the node we're about to mark visited and push into the queue |
if ( m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i ].m_pLinkEnt != NULL ) |
__________________
Мой мод на Xash
Отправлено FreeSlave 08-12-2021 в 19:32:
Да, похоже что-то не так с FSetGraphPointers. Я у себя вижу кучу сообщений **Could not find model.
Надо подумать, куда перетащить этот вызов.
Добавлено 08-12-2021 в 22:18:
Пока что из CBasePlayer::Precache перенес в ServerActivate в client.cpp (пришлось там подключить "nodes.h").
Добавлено 08-12-2021 в 22:32:
Кстати m_pLinkEnt и в обычной халфе неправильно выставляются при сэйв-ресторе. Те же **Could not find model в консоли (выставьте значение developer 4 перед запуском карты, чтобы все сообщения видеть).
Но там баг себя наверно и не проявляет никак, ибо FindShortestPath всегда следует по ветке m_fRoutingComplete.
Да и в целом звать FSetGraphPointers в CBasePlayer::Precache неверно. Что насчёт выделенных серверов, которые запускаются без всяких игроков?
А вот почему даже в сингле энтити не находятся по имени брашевой модели - хз. Возможно при ресторе Precache на энтитях зовется ещё до загрузки последующих, поэтому всех этих брашевых энтитей как бы и нет на момент вызова Precache игрока.
__________________
I'm on github
I'm on opendesktop.org
Отправлено Aynekko 08-12-2021 в 19:34:
Цитата:
FreeSlave писал:
перенес в ServerActivate в client.cpp
Да, помогло! Сейврестор починился. Теперь, как говорится, заживем
Кстати, насчет брейкаблей, у меня пока вот такая полу-рабочая попытка. Это в AdvanceRoute. Комменты оставил на будущее, но пока идей нет.
C++ Source Code:
1 | else if ( WorldGraph.HandleLinkEnt ( iSrcNode, WorldGraph.m_pLinkPool[iLink].m_pLinkEnt, m_afCapability, CGraph::NODEGRAPH_STATIC ) ) |
3 | entvars_t *pevLinkEnt = WorldGraph.m_pLinkPool[iLink].m_pLinkEnt; |
5 | if ( (m_afCapability & bits_CAP_RANGE_ATTACK1) && FClassnameIs(pevLinkEnt, "func_breakable") && !(pevLinkEnt->spawnflags & SF_BREAK_TRIGGER_ONLY) ) |
7 | // ALERT(at_console, "breakable.\n"); |
8 | CBaseEntity *pBreakable = Instance( pevLinkEnt ); |
11 | // UNDONE: should be treating the breakable as enemy and attack it until it breaks, and without shouting "hostiles!" too |
12 | pBreakable->TakeDamage( pev, pev, 15, DMG_CLUB ); |
14 | // this somewhat works but sometimes he doesn't look at breakable and just fighting the air |
15 | // MakeIdealYaw( pBreakable->GetAbsOrigin() ); |
17 | // ChangeSchedule( GetScheduleOfType(SCHED_MELEE_ATTACK1) ); |
__________________
Мой мод на Xash
Отправлено FreeSlave 08-12-2021 в 19:56:
Aynekko, хочешь сделать, чтобы монстры сами разбивали breakable'ы на своём пути? В общем случае лучше такое не позволять. Вдруг это взрывные бочки
В идеале такое можно было бы реализовать только для специально помеченных брекаблей и по-разному для отдельных монстров. Например, вполне можно представить, что агрунт снесёт какие-нибудь коробки просто пройдя сквозь них
А хуман грунты могут использовать пинок для поломки.
__________________
I'm on github
I'm on opendesktop.org
Отправлено Aynekko 08-12-2021 в 20:04:
Цитата:
FreeSlave писал:
хочешь сделать, чтобы монстры сами разбивали breakable'ы на своём пути?
Ну да. В одном месте поставил ящик, а потом туда враги приходят, если игрок его не разбил - то будут тупить там.
Как видишь по коду, с пинком не получилось. Почему-то он не всегда поворачивается на 100% в сторону брейкабли и пинает воздух, выглядит комично. Вообще надо бы флаг задать, да.
А бочки я уже сделал отдельной энтитей - как в хл2 по поведению, только без физики конечно же.__________________
Мой мод на Xash
Отправлено FreeSlave 08-12-2021 в 20:12:
Цитата:
Aynekko писал:
Ну да. В одном месте поставил ящик, а потом туда враги приходят, если игрок его не разбил - то будут тупить там.
В каком смысле тупить? С теми изменениями, что мы обсуждали, они должны ящики считать препятствиями и обходить.__________________
I'm on github
I'm on opendesktop.org
Отправлено Aynekko 08-12-2021 в 20:14:
Хехех, ну так дело в том, что ящик стоит посреди коридора
там никак не обойти. Почему я, собственно, и сделал это вообще.
__________________
Мой мод на Xash
Отправлено Ku2zoff 09-12-2021 в 07:58:
Цитата:
FreeSlave писал:
Я у себя вижу кучу сообщений **Could not find model.
Граф пытается после сейв/рестора прочекать брашевые энтити с моделями вида "*31", "*78", "*102", то есть субмоделями мира. Там какая-то трабла с этим, энтити не находит.
Цитата:
FreeSlave писал:
в целом звать FSetGraphPointers в CBasePlayer::Precache неверно
А, видимо они не успевают отресториться. Надо глядеть порядок вызова DispatchRestore изнутри движка, скорее всего он происходит после прекэша игрока.
Цитата:
FreeSlave писал:
А хуман грунты могут использовать пинок для поломки.
У нодов есть механизм подсказок для AI: m_sHintType. Можно добавить новый хинт "здесь ломать брейкаблю", и ноду с таким хинтом ставить перед ящиками. Во-первых, никто не подорвётся на бочке, во-вторых не будет ломать все подряд коробки, а только те, что рядом с нодой.
Отправлено Chyvachok 09-12-2021 в 14:22:
Ku2zoff еще раз насчет groupinfo, допустим, а как точно этот UTIL_SetGroupTrace работает? Чет я туплю с ним, это надо обоим сущностям ставить одинаковый groupinfo? Просто я так и не понимаю результата конечного. Если той же жертве Барнакла поменять groupinfo это не сломает физику жертве? Я без этого обошелся, оставил pGib->pev->groupinfo = 1; только у Барнакла, без UTIL_SetGroupTrace, это по сути дало то что мне нужно было - барнакл ни с чем не колидит, его труп не мешает проходу и жертва выпадает, и в него регистрируется урон из оружия.
В коде гибсов у меня такой код, я хочу чтобы гибсы с друг другом не колидили, бывает что у них одинаковая позиция и они висят в воздухе, и с жертвой, это правильно написано или нет? Я жертве не ставил groupinfo. Sticky Gib-ы и не работали из-за того что могли с друг другом сколидить и остаться висеть в воздухе.
pGib->pev->groupinfo = 1;
UTIL_SetGroupTrace(pGib->pev->groupinfo, GROUP_OP_NAND);
UTIL_SetGroupTrace(pev->groupinfo, GROUP_OP_NAND);
В общем еще вот, к примеру когда я сделал Акимбо Хорнет заметил, если спавнить Хорнетов сразу при стрельбе с двух рук (первичная стреляет по очереди, левая правая, вторичная сразу с двух рук), и оставить код что подправляет траекторию чтобы они летели в центр экрана - то они в друг друга врезаются и падают, в общем опять же, как этот груп инфо сделать так чтобы если что хорнеты пролетали сквозь друг друга, и в тоже время попадали в НПС и наносили им урон, пусть я и убрал подправление траектории в прицел, все равно видно что они бывают в друг друга врезаются.