* * * Форумы на Наша-Life THREAD * * * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- THREAD : Становимся джедаями, или гравипушка, привязанная к клавише, с регулируемой мощностью Started at 18-06-2009 11:31 by Breever Visit at https://bbs.cs-source.ru/showthread.php?threadid=51022 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 1] Author : Breever Date : 18-06-2009 11:31 Title : Становимся джедаями, или гравипушка, привязанная к клавише, с регулируемой мощностью Вообще, я делаю Star Wars-мод, и самое сложное для меня - это как раз кодинг :) Особенно сложный, связаный с физикой. Вообщем, что надо сделать: при нажатии на определенную клавишу запускается функция, которая в зависимости от времени нажатия увеличивает силу отталкивания обьекта. При удерживании клавиши передвижение и перемещение обзора игрока блокируются. При отпускании обьект, на который направлен прицел, отправляется в полет с N-ной силой :) Алогоритм: 1) создаем в меню настройки клавиатуры новый пункт (файлы config_default.cfg, kb_act.lst) - легко 2) Идем в client.cpp, и дописываем дополнительную команду static ConCommand Force_pull("Force_pull", <Название процедуры>,"<описание процедуры>" ) - тоже реализуемо. 3) Описываем процедуру Force_pull, только хз где конкретно, вроде в Server\hl2\hl2_player.cpp, не забывая указать в hl2_player.h ссылку на нее. - вот это уже трудно Сама процедура, тоже алгоритм: Цикл Если клавиша нажата и мы смотрим на физический обьект, то: - Заблокировать передвижение и перемещение обзора игрока (кстати, какая команда за это отвечает? :) ) - Установить определенную анимацию для игрока (в моде вид будет от 3-го лица) - Увеличить силу удара - Воспроизвести звук - Ждать Х секунд иначе - прервать цикл - Воспроизвести вторую анимацию для игрока - Воспроизвести 2-й звук - Запульнуть обьект, на который смотрел игрок с N-ной силой - Вернуть игроку контроль над персонажем Вообщем, помогите кому не лень пожалуйста, а то я так за неделю не сделаю сам ничего :) Или хотя бы оцените алгоритм, и помогите с определение его местоположения :) Так-то можно спереть от гравипушки много чего ) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 2] Author : KLIMaka Date : 18-06-2009 12:23 Во-первых стот понимать, то все уже изобретено до нас, стоит лишь све это найти и повернуть себе во благо. Во-вторых я уже давно обрисовал некую общую структуру, которая подходит в 99% к процессу кодинга под Сурс ([url]https://bbs.nashalife.ru/showthread.php?s=&postid=752441#post752441[/url]). Обрати особое внимание на первые 2 пункта. И броски объектов, и фриз управнения, и анимации и звуки - все это есть в исходниках, просто нужно их найти. Но нужна сущая малость - навыки в программировании. Если их нет, то твой пост сводится к "напишите за меня это и это". Вряд-ли кто-нибудь на это согласится. Если они есть, то исходники тебе в руки - они главное, достоверное, и почти всегда единственное место, откуда можно почерпнуть практически все об Сурсе. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 3] Author : Breever Date : 18-06-2009 12:33 Я конечно это понимаю, в принципе, так и анализируя, я и хочу сделать все, что надо. Никого я не призываю писать за меня что-то, только прошу прокомментировать алгоритм и дать советы (мол сначала используй трассировку, потом обрабатывай результаты, потом запускай объект) Просто если алгоритм неправильный, то над его реализацией можно и месяц пыхтеть - ничего не получится :) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 4] Author : KLIMaka Date : 18-06-2009 13:14 Вот пример тебе - нужен, например ДоФ шейдер. Пишем алгоритм: - оттрасировать точку, в которую смотрит плеер - передать длинну трейс-лайна в шейдер - для каждой точки экрана узнать ее глубину, и в зависимости от результата сравнения с длинной трейс-лайна как-то блурить эту точку. Все вроде правильно. Алгоритм правильный.... Но есть одно очень большое НО! Алгоритм правильным будет оставатся ровно до того момента, пока ты не начнешь его реализовывать. Ибо когда ты начнешь все это делать, то увидишь, что както странно начинают выделятся границы объектов с большой разницей глубины. Бамц! Алгоритм уже не настолько правильный, приходится переделывать. Переделал... Снова Бамц! Оказывается у нас нет на руках полного depth-range! Опять алгоритм не правильный! Опять переделывать, причем координальным образом. И т.д.... И это не синтетика, это я тебе из реального опыта рассказываю. Это я все к тому, что пока не возьмешься, не узнаешь, правилен твой алгоритм или нет. Пока у тебя вроде все стройно и хорошо выглядит, дай бог чтобы так и осталось. Хотя Интересно кого ты будешь толкать, если цель, за время твоего накопления смоется )) Вообще этот момент обдумывать нужно, здесь больше бы подошел способ поиска всех физ объектов в конусе перед игроком, и применение к ним силы, пропорциональной расстоянию игрока до них. Во-вторых при воздействии на НПС прийдется либо их насмерь убивать (и толкать рагдолл), либо не трогать вообще. И т.д. и т.п. Предварительный план - это замечательно, но потрудись пробить почву перед построением планов. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 5] Author : Breever Date : 18-06-2009 13:29 Ну уже прописал в скриптах, осталось только написать 2 процедурки непосредственно толкания. Про цель смоется - это интересно, надо подумать :) Ну видимо будет просто толчек в никуда. Кстати самый главный вопрос: Возможно ли реализовать, чтобы враги после того, как схватят толчек, превращались в рагдоллы, но затем вставали обратно, если еще живы (как это есть в Dark Messiah) Убить-то не трудно, а вот воскрестить из рагдолла, это уже хуже, да и примеров этому в исходниках вроде нету. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 6] Author : KLIMaka Date : 18-06-2009 13:41 Конечно возможно. Возможно вообще все! Были бы навыки время и желание. В теории это выглядит примерно так: - регдоллим НПС, он улетает куда-то, с раскинутыми ручками-ножками - лежит так недолго - потом мы начинаем блендить регдолл до начального состояния анимации подьема с земли. - как только доблендили, запускаем анимацию подьема. Опять-же алгоритм вроде простой, пока его реализовывать не начнешь. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 7] Author : manJak Date : 18-06-2009 15:38 Хмм. Мне одному показалось, что алгоритм функции включает цикл [i]в себя[/i]? о_О Breever, ты так добьёшься только повисновения игры) Потому что во время цикла игра будет стоять и не сможет отреагировать ни на действия игрока, ни на что вообще) Код этого цикла тебе придётся приткнуть в какое-то другое место. В Think-функцию оружия, например. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 8] Author : Breever Date : 18-06-2009 16:49 Почти исправил сам, уже полтора часа парюсь над этой фигней Оо [size=1][i]Breever добавил [date]1245343306[/date]:[/i][/size] Ну вообщем, во всем разобрался, просто я вообще на С++ мало программировал, хорошо шарю только в делфи. Но тем не менее, остается одна противная ошибка: [CODE] Compiling... client.cpp .\client.cpp(655) : error C3861: 'LaunchObject': identifier not found [/CODE] Здесь, как я понял, один из аргументов функции не впорядке. Вообще же, это стандартная функция от гравипушки, заголовочный файл которой я подключил нормально. Сама моя функция выглядит следующим образом: [CODE] // ======== FORCE_PULL ======== void CC_Force_pull( void ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); // Инициализируем игрока, без этой строки pPlayer не робит Оо PLAYER_ANIM playeranim = PLAYER_ATTACK1; // ставим любую анимку Vector vstart = pPlayer->Weapon_ShootPosition(); // Начало линии трассировки Vector vend; // конец линии трассировки QAngle ang = pPlayer->EyeAngles(); // получаем углы зрения AngleVectors (ang, &vend); // Конец линии трассировки (угол в вектор) trace_t tr; UTIL_TraceLine( vstart, vend, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr); // трассируем из start в end, по маске выстрела, игнорируя себя, без коллизий, записываем в переменную tr if (tr.fraction != 1.0) //проверяем, достигла ли трассировка конца { LaunchObject( vend, 2000.0 ); // пуляем обьект с силой 2000 } return; } static ConCommand Force_Pull ("Force_pull", CC_Force_pull, "Force pull jedi ability"); [/CODE] Тут уж вообще не понимаю в чем дело и что не нравится компилятору Оо Помогите отловить ошибку? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 9] Author : KLIMaka Date : 18-06-2009 18:38 Во-первых LaunchObject не член глобального пространства имен, на это компилятор и жалуется. LaunchObject - это член класса CWeaponPhysCannon. Что это обозначает, поситай в любой книжке по ООП и С++ Во-вторых, (но это уже не существенно из-за сказаного выше) LaunchObject запускает объект, прикрепленный к m_grabController`у, который опять-же обьявлен в CWeaponPhysCannon. Копай глубже. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 10] Author : Breever Date : 19-06-2009 04:36 Ясно, это оказывается методы класса, я чет не обратил внимания и использовал их как просто функции. А каким тогда образом оформить ссылку на класс? Или же, если нужно неприменно сделать свой на основе CWeaponPhysCannon, то каким образом? Он ведь не найдет базовый класс, если просто написать "class CForce_pull : public CWeaponPhysCannon;" P.S. В инете прочитал только про наследование, если все классы описываются в одном файле, у нас же получается в разных Оо ===================================== Как так, смотрю даже на примере гаус-пушки из туторов, она сделана как отдельный класс, наследующий признаки CBaseHLCombatWeapon, пытаюсь найти как это сделано - иду в "basehlcombatweapon.h" (т.к. он подключен в заголовочных файлах) и никакого класса там ни нахожу, каг таг? Оо ====================================== короче нихера не понимаю, что вообще за хрень такая ====================================== Максимум чего сам добился за это время: [CODE] 1>.\client.cpp(657) : error C2027: use of undefined type 'CWeaponPhysCannon' 1> d:\Games\Steam\MyMod\src\game\server\hl2\weapon_physcannon.h(33) : see declaration of 'CWeaponPhysCannon' 1>.\client.cpp(657) : error C3861: 'LaunchObject': identifier not found [/CODE] Теперь видимо ему просто не нравится как в weapon_physcannon.h описан класс CWeaponPhysCannon, как его еще по-другому-то описать, чтобы я смог из client.cpp наследовать его методы, а главное функцию LaunchOgject???????? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 11] Author : freeman85 Date : 19-06-2009 07:26 1> d:\Games\Steam\MyMod\src\game\server\hl2\weapon_physcannon.h(33) : see declaration of 'CWeaponPhysCannon' Похоже ты пытаешься назвать свой класс так же как старый, оно говорит, что CWeaponPhysCannon уже объявлен 1>.\client.cpp(657) : error C2027: use of undefined type 'CWeaponPhysCannon' Походу последствие следующей ошибки, хотя не помню, что бы у меня когда-нибудь писало type. Ещё тогда версия, что ты не правильно объявил код public|private. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 12] Author : Breever Date : 19-06-2009 07:48 Не, пока свой класс я не создавал. Вообщем, там ситуация такая: Моя функция находится в client.cpp, в ней требуется использовать функции, являющиеся методами класса CWeaponPhysCannon. Обнако грамотно обьявить и сослаться на weapon_physcannon у меня не получается, даже подключив в модулях weapon_physcannon.h. Описания class CWeaponPhysCannon ведь там нету, оно находится не в заголовочном файле, а в самом cpp. Вот я и пытался написать в weapon_physcannon.h обьявление о том, что в weapon_physcannon.cpp содержится этот самый класс, компилятору не понравилось. Вообще, сделал это я просто вот так: [code]class CWeaponPhysCannon;[/code] На это компилятор как раз и выругался -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 13] Author : manJak Date : 19-06-2009 10:00 Нудык правильно, что выругался) Нельзя использовать просто объявленный класс (максимум, что можно - создавать/передавать указатели на него), компилятору нужно его определение. А поскольку определение какой-то умник из вальвы запихнул в цппшник, остаётся только его оттуда вытащить в отдельный хедер. Но всё это тщетно, потому что метод, который ты хочешь вызвать - не статический. :) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 14] Author : Breever Date : 19-06-2009 10:42 Угу, мне тоже не понравилось, что функциональность реализована не отдельными функциями, а методами класса Оо Ну дык я хочу поюзать не весь метод, а только куски из него :( А есть еще обычные команды применения силы к определенному обьекту? Вот эта функция не подойдет: [code] // Applies force impulses at a later time void PhysCallbackImpulse( IPhysicsObject *pPhysicsObject, const Vector &vecCenterForce, const AngularImpulse &vecCenterTorque ); [/code] Вроде как она применяет импульс силы (любимая физика! :) ) на короткое время. Только вот с ее параметрами не совсем все ясно. 1 параметр - сам физ. обьект, получить ссылку на него можно при помощи трассировки 2 параметр - как я понял вектор приложения силы, получаем также трассировкой 3 параметр - какой-то угловой импульс, где его брать?? P.S. И да, я нубопрограммер :Р -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 15] Author : manJak Date : 19-06-2009 12:00 Всё куда проще) // force vector is direction & magnitude of impulse kg in / s virtual void ApplyForceCenter( const Vector &forceVector ) = 0; Итого: if ( tr.m_pEnt && tr.m_pEnt->VPhysicsGetObject() ) tr.m_pEnt->VPhysicsGetObject()->ApplyForceCenter( dir*1000.0f ); -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 16] Author : Breever Date : 19-06-2009 14:22 жесть Оо Оказывается все понятнее и проще, спасибо. =================================== Ппц, ну тут я уже просто хз. Компилятору все нравится, но в игре когда я нажимаю кнопку.... БАЦ.... и нихрена не происходит :( ВСЕ ДОЛЖНО РАБОТАТЬ, ПРОВЕРИЛ 1000 РАЗ! Причем в стандартно используемых ситуациях и функциях все это робит Оо Вот моя процедура: [CODE] // ======== FORCE_PULL ======== void CC_Force_pull( void ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); // Инициализируем игрока, без этой строки pPlayer не робит Оо PLAYER_ANIM playeranim = PLAYER_ATTACK1; // ставим любую анимку Vector vstart = pPlayer->Weapon_ShootPosition(); // Начало линии трассировки Vector vend; // конец линии трассировки QAngle ang = pPlayer->EyeAngles(); // получаем углы зрения AngleVectors (ang, &vend); // Конец линии трассировки (угол в вектор) trace_t tr; // переменная для трассировки UTIL_TraceLine( vstart, vend, MASK_SHOT, NULL , COLLISION_GROUP_NONE, &tr); // трассируем из start в end, по маске выстрела, ничо не игноря, без коллизий, записываем в переменную tr Vector vforce; // вектор направления силы (по идее он дублирует vend, но для прикола пусть будет :) pPlayer->EyeVectors( &vforce ); // заполняем переменную вектором, полученным из углов зрения игрока if (tr.m_pEnt && tr.m_pEnt->VPhysicsGetObject() ) // проверяем: если трассировка была И если ентря - физ. обьект { // то... tr.m_pEnt->VPhysicsGetObject()->ApplyForceCenter( vforce * 1000.0f ); // применяем к этому обьекту центросилу в векторе vforce умноженом на 1000 } return; } static ConCommand Force_Pull ("Force_pull", CC_Force_pull, "Force pull jedi ability"); // сама команда, единственная строчка, которая РАБОТАЕТ! Оо [/CODE] Ну тут ВСЕ проверено и правильно, как так???? =========================== попробовал заменить ApplyForceCenter( vforce * 1000.0f ); на ApplyForceCenter( tr.endpos * 1000.0f ); Получается аналогичная фигня - ничего не робит Оо -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 17] Author : Breever Date : 22-06-2009 05:14 Ураа, все получилось, есть правда мелкие недочеты, но с ними самостоятельно разберусь. И правильно говорит KLIMaka, исходники - лучший учебник :) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 18] Author : manJak Date : 22-06-2009 13:57 А не работало потому, что UTIL_TraceLine принимает на направление трейса, а конечную точку. ^_^ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 19] Author : Breever Date : 22-06-2009 16:21 ну да, все верно. Просто второй аргумент функции задается как A + B * дистанцию, я это в исходниках как раз и нашел. Только там еще одна фишка, нужно использовать не ApplyForceCenter, а ApplyForceOffset, чтобы предметы летели не к центру карты, а от игрока. Кстати долго мучился как это сделать, потом додумался использовать в качестве 1 аргумента плоскость обьекта, получаемую в результате трассировки, т.е. tr.plane.normal. Сейчас закончу со звуками и выложу уже рабочую функцию, может кому-нибудь понадобится :) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 20] Author : manJak Date : 22-06-2009 18:18 > нужно использовать не ApplyForceCenter, а ApplyForceOffset, чтобы предметы летели не к центру карты Странно. По всей логике ApplyForceCenter применяет силу к центру масс объекта в указанном направлении. о_О (А ApplyForceOffset - из указанной точки в указанном направлении. Вроде.) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 21] Author : Breever Date : 23-06-2009 03:59 Ну может, просто тогда я наверное еще не нормалью пользовался, и все обьекты летели в одну и ту же сторону. Кстати ApplyForceOffset дает неплохой вращательный момент, поэтому наверное правда надо попробовать переделать на ApplyForceCenter. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 22] Author : manJak Date : 23-06-2009 15:17 > ApplyForceOffset дает неплохой вращательный момент Ну да, он для того и предназначен, чтобы пихать объект в произвольную его точку) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 23] Author : Breever Date : 23-06-2009 17:37 Ну вообщем-то все получилось, обьект летит идеально вперед, как от гравипушки. Сейчас только разберусь с анимками и поставлю задежку на применение способности, тогда выложу полностью готовую функцию. Ну и потом надо будет добавить возможность пихать НПС. Кстати приступил уже к созданию следующей способности - молния. Уже сделал всю базу, осталось написать только функциональность самой молнии. Кстати, подскажите идеи для реализации следующей способности, вот как она должна выглядеть: Игрок наводит прицел на физ. обьект, нажимает кнопку и удерживает ее. Пока он держит кнопку, сам персонаж замораживается (это уже не проблема сделать, временное отключение кнопок научился делать, просмотрев код приближения (ZOOM) ), однако может двигать этот обьект в любон направлении (W/S - по оси X, A/D - ось Y, SPACE/CTRL - ось Z) также при нажатии на кнопку мыши обьект пуляется вперед, как на моей Force_pull-функции. В принципе, все, кроме перемещения обьекта в пространстве я могу сделать. Подскажите пожалуйста идеи, я вообще планировал поизучать код гравипушки, но там только отдаленно нужное мне. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 24] Author : KLIMaka Date : 23-06-2009 17:59 Ну как вариант можно присваивать объекто MOVE_TYPE_FLY ( что-то типо этого, точно не помню) Что заставит двигатся объект без воздействия гравитационных сил. А потом пожно тем же ApplyForceCenter с небольшим значением сиилы заставлять объект двигатся в необходимом направлении. Както так )) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 25] Author : Breever Date : 23-06-2009 18:26 ууу, точно, спасибо, пример этому найду в ноуклипе у плеера. И еще один интересующий вопрос, и займусь ближайшее время реализацией этого всего сразу :) :wow: Как "воскресить" НПС из рагдолла. По-моему стандартные рагдольные функции убивают его (по-моему, потому что я пока не со всеми аргументами разобрался). Даже поблендить нпс я сам найду как, но вот как поднять не понимаю :( Ну меня вот заинтересовала одна из них: BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags ) А конкретно понравился параметр duration. Это ли не время, на которое цель превращается в рагдолл? Если так, то очень даже отлично, тогда появляется следующий, более легкий вопрос: как определить, что рагдол уже спокойно лежит на земле, его никто не трогает (и следовательно уже пора вставать :) ) Если я не прав, и это продолжительность чего-то еще, то как все-таки реализовать возвращение из рагдола в НПС? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 26] Author : KLIMaka Date : 23-06-2009 22:46 Ну насколько я помню, третий аргумент в BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags ) задает время конвульсий )) Ибо ф-я то создает дергающийся рагдолл (от этого и название Boogie ) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 27] Author : Breever Date : 24-06-2009 04:37 А, да, не зря такая маленькая продолжительность стоит у целей, убитых катающейся миной :) Так все-таки, какую тогда функцию использовать, если это возможно - вернуть цель к жизни. Если нет, то прокатит ли такой алгоритм: 1) Цель хватает толчек, ее текущие жизни записываются в переменную. От них отнимается где-то 10 хп. 2) Запустить рагдолл с силой 3) Если цель не сдохла от этих -10 хп, то подождать, пока ее рагдолл успокоится. (как это узнать? :unknown: ) 4) Убрать рагдолл, породить НПС в спящем состоянии (чтобы не кинулся ни на кого :) ) и с записаным здоровьем в точке, где лежал рагдолл 5) Присвоить нпс анимку лежащего на земле. 6) Проиграть анимку подьема, разбудить нпс. Вообщем, если такой алгоритм, то остается только 2 вопроса - как узнать, что рагдолл уже лежит и как сделать тупо паузу в функции? (я наверное запущу цикл: пока рагдолл не будет лежать, ждать 1 сек, иначе пошли дальше пункты 4,5,6) Но лучше бы конечно, если какая-нибудь рагдольная функция работала, не убивая ) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 28] Author : manJak Date : 24-06-2009 09:43 > одождать, пока ее рагдолл успокоится. (как это узнать?) Точно не скажу, но мне кажетца должна сработать проверка IsAsleep() у каждого лимба регдолла. Что касается паузы в функции, то не всё так просто.. Я бы, наверное, написал класс-манагер (от CAutcs-sourceSystemPerFrame или типа него) для "менеджемента" полудохлых неписей, в котором хранил бы список структурок со всей необходимой инфой для воскрешения каждого нпц. Там же и своего рода таймеры можно хранить, проверяя их состояние в функции FrameUpdatePostEntityThink. Короче не для новичка в ц++ задачка. :D А алгоитм в общем верный. Не хватает только плавного бленда регдольных костей в начальную позицию анимации, но это опять же явно не тривиальная задача и лучше про неё пока забыть) [size=1][i]manJak добавил [date]1245833101[/date]:[/i][/size] OMGWTF?? Форум заменил "оGаmе" на "cs-source". Голактеко опасносте! -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 29] Author : Breever Date : 24-06-2009 11:13 Хм, как так, ведь в том же Delhpi и C++ есть функция Sleep (cardinal msec), неужели в движке нет чего-нибудь аналогичного Оо Ну когда рагдолл успокоится можно узнать по флагам, есть такой интересный флаг, как ON_GROUND (как-то так). Просто после него поставить маленькую паузу (чтобы удостоверится, что он уж точно спокойно лежит) и продолжить алгоритм. Ну вообще, переодическую проверку можно сделать, как это есть в hl2_player.cpp выполняется проверки на зум и т.п. Но как-то проще было бы с обычным циклом и паузой :( Мож KLIMaka увидит и посоветует что-нить :) Вообще, можно и без паузы, просто будет цикл выполняться, пока НПС не ляжет, но это же будет грузить систему Оо :( Да и для следующего всего мне понадобится пауза :) ====================================== P.S. Нашел функцую SetWait(), попробую применить ее к рагдоллу. Вообще, эта функция член класса CAI_BaseNPC, но поидее должно получится, потому что сначала мы делаем [B]нпс[/B], рагдоллом, а потом ему же говорим жди, пока не будут определенные флаги. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 30] Author : KLIMaka Date : 24-06-2009 12:57 Забудь обо всех этих циклах и Слипах! Это асинхронное приложение и ты должен постоянно отдавать управление на все остальные блоки. Для того, чтобы оставлять объект на время самому себе есть Think ф-ии. Установив для некой энтити NextThink( time ) ты укажешь на то, что управление к этой ентити вернется через time секунд. Т.е. через time секунд вызовется метод Think для данного объекта. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 31] Author : Breever Date : 24-06-2009 13:25 Да уж, не сразу перестраиваешься с программирования в одном потоке в Borland Delphi \ C++ на несинхронное приложение :) Спасибо за ответ, сам бы дооолго искал эти Think, хотя и скользил не раз по ним взглядом. Ну и в SetWait необходимость отпала сразу. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Post 32] Author : Breever Date : 24-06-2009 17:18 Блин, одни косяки как обычно пошли. Самое интересное, что не работает пауза, хотя я вроде говорю НПС, что надо think. Ну если конкретнее, то пара вопросов по самой функции: [CODE] if (tr.m_pEnt->IsNPC() && !tr.m_pEnt->IsEFlagSet( EFL_NO_MEGAPHYSCANNON_RAGDOLL ) && tr.m_pEnt->MyNPCPointer()->CanBecomeRagdoll() ) { pullDir = vstart - tr.m_pEnt->WorldSpaceCenter(); // вектор пуляния нашего НПС float CurrentLife = tr.m_pEnt->GetHealth() - 10; // записываем жизни и отнимаем 10 (урон от толчка) CTakeDamageInfo info( pPlayer, pPlayer, 0.0f, DMG_GENERIC ); // информация об уроне (для галочки, чтобы функция не ругалась :) tr.m_pEnt->MyCombatCharacterPointer()->BecomeRagdoll ( info, -pullDir * 9000.0f ); // Сделали НПС рагдоллом и запульнули его. if (CurrentLife > 0) // если после всего этого наш НПС еще жив { tr.m_pEnt->SetNextThink ( gpGlobals->curtime + 4.0f); // пусть полностью улежится CBaseEntity::Create((char*)STRING( tr.m_pEnt->GetEntityName() ), tr.m_pEnt->GetAbsOrigin(), -ang ); // создаем такого же НПС, в последней точке, обращенного взглядом к игроку (чтобы он не потерялся и сразу увидел врага) UTIL_Remove (tr.m_pEnt); // убираем наш рагдол } } [/CODE] Функция неполная, оставил только самое главное и проблемное - Ну самое главное - почему не работает пауза? - В чем ошибка на первом аргументе функции CBaseEntity::Create? В самой игре он пишет unknown type entry. (ну с этим методом проб может и смог бы разобраться) - И еще довольно интересный вопрос: Вот я применяю функцию BecomeRagdoll к tr.m_pEnt, а после этой функции можно ли обращаться к ней также, tr.m_pEnt?? Просто там ведь идет Think дальше, может поэтому он не работает? - И кстати, как обращаться к новоиспеченной энтри, которая создастся командой Create?? Ее ведь нужно будет усыпить, дать ей подумать, поставить анимки и т.д. Короче я нубас, и этим все сказано :unknown: :( -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- The messages has been download from Форумы на Наша-Life at https://bbs.cs-source.ru at 11.11.2024 11:43:23