Перейти к контенту

Malandrinus

Жители
  • Число публикаций

    1 930
  • Регистрация

  • Последнее посещение

  • Дней в топе

    13
  • AMKoin

    160 [Подарить AMKoin]

Весь контент пользователя Malandrinus

  1. SkyLoader, Идея интересная, однако есть несколько моментов. Для начала, на чистой игре нет движкового способа просоединить актора к объекту типа CHolderCustom. Значит нужны правки, и всё становится не так просто. Потом, появятся дополнительные проблемы. Нужно будет убирать на время использования фейковый объект, поскольку он находится в том же месте, что и турель. Где-то будет торчать собственно сама турель, и возможно это место будет достижимо актором, и турель эта будет видима, и её можно будет использовать с понятными последствиями. Я пока не знаю, может ли турель на родном класса использоваться скриптами, как веротолёт или машина, но это было бы желательно. Короче, по всему выходит, что решение не намного лучше, чем, скажем, решение на основе машины. Тоже нужны костыли в виде скриптов и правок движка. Artos, ничего сложного с турелью нет. Секции stationary_mgun или mounted_weapon. Это два разных класса оба для станкового оружия. Один из них кажется более доделан, чем другой, но я не помню какой именно. Визуал у них должен быть уже прописан прямо в секции, и модель в ресурсах игры тоже вроде как есть. При спавне прямо перед актором объект на мгновение даже появляется, но потом исчезает. Я подробно с этим не разбирался, но походу переносится в начало локации (так мне говорили). Кроме того, я не уверен на самом деле, что при юзании объекта актор переносится в место спавна турели, а не ещё куда-то. Кстати, если судить по информации о том, что в билдах турель работала как надо, то я больше склоняюсь к мысли, что объект был не недоделан, а именно не переделан на некоем этапе. Можно обратить внимание, что физические объекты в игре имеют одним из базовых классов CPHSkeleton, а вот эти два класса турелей - нет. Может в этом дело.
  2. edwin0, Если не ошибаюсь, это было сделано примерно так: актор телепортируется постоянно относительно вертолёта, таким образом как-бы летит вместе с вертолётом. С другой стороны сам вертолёт управляется скриптом и отслеживает направление актора. Соответственно летит туда, куда смотрит актор. Детали остального не знаю, в том числе как там управляли скоростью и оружием. В то время возможностей ловить ввод от актора было мало, разве что fov оружия измерять или патроны в текущем оружии. Я не уверен даже, что там вертолёт не самодеятельно стреляет, без участия актора вообще. На то время конечно было круто, хотя применимость в реальном моде весьма ограниченная. Куда там летать то, на пятачке в 500 метров? =) Artos, Там не так, объект как-бы и есть и находится на своём месте, но его визуал торчит чёрт те где. Если туда пойти и взяться за пулемёт, то вроде как окажешься там, где объект был заспавлен и пострелять из него можно. Опускаешь - оказываешься опять там, где стоит мировая модель. Я на самом деле не уверен, что при использовании пулемёта переношусь туда, где он заспавнен. Я тестировал на маленькой тестовой локации. Там было не понять, где точно находишься.
  3. Насколько я знаю, до сих пор делали турели на основе класса вертолёта или автомобиля. Можно управлять таким пулемётом скриптово, т.е. это будет автономная сущность, однако, из него не пострелять актору. Теоретически на основе машины можно сделать пулемёт для актора, но весьма муторно. Рабочих же пулемётов в финалке на основе родных классов станкового оружия вроде как не делал никто. Собственно, если бы удалось решить проблему появления визуала объекта в неправильном месте, то работало бы просто так: заспавнил любым способом и сразу работает. И не нужны бы ли бы ни скрипты, ни извраты с моделями. По моему, что-то там накосячено с пересчётом координат при переходе из режима худа и обратно, но уверенности нет.
  4. Artos, Там не в скриптах дело. Проблема в самом движковом классе станкового оружия. Когда создаёшь объект, он почему-то визуально находится не на том месте, где его создал, а где-то в начале локации. Если с точно тем-же визуалом создать обычный физический объект с такими же ровно координатами, то он создаётся нормально (хоть и не стреляет разумеется), так что проблема не в визуале и не в методе спавна, а именно в движковом классе. Эти объекты архаичные, на каком-то древнем этапе разработки в вигре были, но до релиза не дошли. По всей видимости что-то где-то было изменено в общем классе оружия, а эти объекты соответственно не обновили. Или может просто исходно не доделали. Кто теперь скажет наверняка...
  5. vasya092, покажи, как ты создаёшь неписей. Судя по твоему удалённому сообщению я не вполне уверен, что ты на самом деле это понимаешь.
  6. vasya092, предметы создаются точно также, как NPC.
  7. proper70, KD87, Чем тратить время на поправление, лучше прописать в ридми, с какой версией будет работать. Вообще, зачем обновлять что-то на новую версию, если и со старой прекрасно работает?
  8. Callisto, это исключительно вопрос библиотек. В штатных библиотеках Lua, описанных в официальном мануале, таких возможностей вроде нет. Вообще говоря, Lua не больно силён в автономном варианте, и набор стандартных библиотек весьма беден. Подразумевается, что Lua - это всё же в основном расширение хост-программы.
  9. Есть один нюанс языка, которому мало кто уделяет внимание. В Lua, как в языке с сильным акцентом на использование ссылок, надо делать различие между понятиями "ссылка" и "значение". Переменная в Lua - это ссылка на значение. У ссылки как таковой нет типа, тип есть только у значения, на которое эта ссылка ссылается. Типы всем известны: число, строка, таблица, userdata, логическое значение и nil. Я обращаю внимание, что nil - это всего лишь одно из возможных значений, на которое может ссылаться переменная. Далее станет ясно, почему это важно. Имена даются ссылкам, индексированная позиция в массиве или ключ в ассоциированной таблице - это тоже ссылки. Если кто не знает, то обычные именованные переменные - это на самом деле тоже значения из специальных таблиц - отражающих область видимости. Это не так очевидно, но ссылки, вообще говоря, ведут себя так-же, как обычные стековые переменные, скажем, в СИ или в любом другом традиционном языке. Теперь что со сборкой мусора. Сборщиком мусора собираются значения, на которые больше нет ссылок. Возьмём обычную переменную внутри функции. function f() local a = "str" end Здесь вроде бы всё понятно, есть локальная переменная с именем "a" со значением "str". Мы говорим, что по выходу из функции переменная вышла за область существования и была удалена сборщиком мусора. При этом обычно не делается акцента на разделении "ссылка/значение". Однако, если рассматривать эту ситуацию более пристально, то происходит следующее. - По выходе из функции удаляется стек функции - Соответственно удаляется находящаяся в стеке ссылка с именем a - Это приводит к тому, что на значение "str" больше нет ссылок - Что в свою очередь приводит к тому, что это значение, где-то там находящееся, будет удалено сборщиком мусора. Чтобы иллюстрировать этот механизм, рассмотрим иную ситуацию. function f() local a = "str" a = nil a = 1 a = nil end Здесь мы: - завели локальную переменную (ссылку) с именем "a". - сразу присвоили ей значение "str" - затем присвоили её значение nil, что привело к тому, что на значение "str" ссылок больше нет и оно будет убрано сборщиком мусора когда-то. Но ссылка осталась! - и далее мы присваиваем этой-же ссылке другое значение, другого типа (на этот раз "number") - и затем опять присваиваем всё той-же ссылке значение nil, что приводит к тому, что на значение 1 ссылок больше нет, и оно будет убрано сборщиком мусора. - при выходе из функции ссылка "a" будет удалена, но, повторюсь, не сборщиком мусора, а вместе со стеком функции. Справедливости ради надо заметить, что значения типа "nil", "number" и "boolean" имеют фиксированный и малый размер, и поэтому хранятся прямо в ссылке, а не в динамической памяти. По этой причине их не требуется удалять сборщиком мусора, поскольку их удаление по сути осуществляется в ходе замены значения ссылки другим значением. Это всего-лишь оптимизация и на общей идее никак не сказывается. Вот ещё одна ситуация, где идея ссылка/значение становится более важной и заметной: a = "str" function f() local a for ... do a = 1 end print(a) end print(a) - имеется глобальная ссылка с именем "a", которая ссылается на строковое значение "str" - мы создали локальную переменную (ссылку, помните?) в стеке функции. Вопреки расхожему мнению, это не неинициализированная ссылка! Согласно правилам Lua она имеет значение nil. - в последующем блоке мы обращаемся к ссылке "a", но к какой именно? Вот здесь важно, что ранее мы создали ссылку с тем-же именем "a" внутри функции. Поскольку эта ссылка существует и имеет область видимости "ближе", нежели глобальная ссылка с тем же именем снаружи функции, то именно они и будет использована. - таким образом, именно локальная ссылка будет ссылаться на численное значение "1" - по выходе из функции локальная ссылка будет удалена вместе со значением "1", а глобальная останется и сохранит своё значение "str". Теперь, какое это всё отношение имеет к таблицам. В таблицах хранятся именно ссылки, а не значения. Поэтому, есть в общем разница между действием "удалить элемент таблицы" и "записать nil в элемент таблицы". Разница эта проявляется не всегда. Чтобы понять когда именно, надо к сожалению знать детали реализации языка. Таблицы имеют две части: часть "ассоциативный массив", т.е. с индексами общего вида, и часть "массив", т.е. "с целыми индексами, идущими без разрывов от единицы". Для ассоциативного массива в общем разницы нет, удаляем мы ссылку или пишем в неё nil. В самом деле, при взятии значения по ключу мы получим nil, как в том случае если мы ранее записали по этому ключу nil, так и в том, если такого ключа там никогда не было. Если подумать, то если даже ссылка там остаётся, то мы именно такой результат и получим - nil в любом случае. При переборе же циклом любого вида очевидно алгоритм попросту игнорирует ссылки со значением nil. Признаться, я не помню уже детали реализации, т.е. упаковывается ли там массив после записи nil по ключу или нет, но это и не важно. Вы всё равно нельзя стандартными средствами языка узнать реальный размер этой части таблицы. А вот где становится важно понятие о ссылках и значениях так это для части массива. Дело в том, что записывая nil по индексу массива мы делаем именно это, записываем в имеющуюся ссылку другое значение (а именно nil. Помните? Это всего лишь одно из возможных значений.). При этом с остальными ссылками ничего не происходит, никак массив не перепаковывается, индексы остаются на своих местах. Просто по одному из индексов сидит nil. К чему это приводит? Вот здесь и начинаются танцы с бубном. Создатели языка, видимо желая упростит описание, никак не акцентировали внимание на ссылочной природе происходящего. Из-за этого в ряде случаев имеется противоречивость. К примеру возьмём такой случай: t = {12,34,56} t[2] = nil for i,v in ipairs(t) do print(i,v) end for i,v in pairs(t) do print(i,v) end for i=1,#t do print(i, t[i]) end алгоритм перебора в цикле с использованием ipairs (первый вариант) перебирает до ближайшего nil, если идти с первого индекса, т.е. выведет только 12. Алгоритм перебора, с использованием pairs (второй вариант), выведет все значения "не nil", т.е. 12 и 56. Здесь пока всё работает в соответствии с правилами языка. А вот оператор # (взятие длины) будет возвращать длину массива без учёта дырки, и значит перебор массива по индексу (третий вариант) выдаст все три значения 12, nil, 56. Т.е. что происходит, есть часть таблицы "массив". Если я пишу в эту часть значение nil по одному из индексов, то это просто означает, что я записал nil, в одну из ссылок, хранящихся в этом массиве. Саму ссылку это действие не удаляет. Это влияет на те алгоритмы, которые в своей работе учитывают значения ссылок, а именно ipairs и pairs. А вот оператор взятия длины (#) очевидно значения по ссылкам в части таблицы "массив" не читает, а просто выдаёт его длину. Теперь ещё веселее. Возьмём такую ситуацию: t = {1,2,3} t[6] = 45 t[4] = 12 t[5] = 34 t[2] = nil print(#t) Этот код выведет значение 6, а вот такой: t = {1,2,3} t[6] = 45 t[4] = 12 t[5] = 34 t[4] = nil print(#t) выведет 3 Т.е. здесь мы имеем таблицу, где непрерывно идущие от единицы индексы имеют сложную историю формирования. В данном случае часть индексов 1-3 заведомо была создана как массив, в том время как остальные были добавлены вразнобой. Таким образом, если мы делаем дырку в первой части, то опертор длины её игнорирует, а если во второй, то учитывает. Было бы логично предположить, что оператор взятия длины сначала просто берёт длину части-массива, затем перебирает все элементы начиная со следующего и до дырки, однако вот такой код: t = {1,2,3} t[6] = 45 t[4] = 12 t[5] = 34 t[5] = nil print(#t) уже выдаёт 6, что в общем оставляет одни вопросы, как именно это там внутри работает, и какая оптимизация приводит к этому результату. К сожалению, эти вопросы нельзя игнорировать полностью, только слепо упираясь в официально озвученный синтаксис языка. Вот типичный пример, который практически важен, но несёт в себе именно это противоречие. Допустим, я передаю в функцию произвольное число аргументов. Я мог бы написать обработку этого случая так: function f(...) local args = {...} for i,arg in ipairs(args) do end end К сожалению, если среди аргументов встречается nil, что вполне может получиться на практике, то цикл перебора ipairs на этом остановится, и аргументы, идущие за nil, будут опущены. Однако, используя особенность оператора # игнорировать нулевые ссылки в массиве, я могу написать так: function f(...) local args = {...} for i=1,#args do local arg = args[i] end end Это позволит перебрать все аргументы, независимо от их значения.
  10. Kirgudu, там всё правильно. Второй случай - это когда интервал содержит переход через границу суток, когда нижняя граница диапазона численно больше верхней.
  11. Dennis_Chikin, цикл until - это выполнение до тех пор, пока условие не станет истинным. until в переводе - это "до" или "пока не". Эх молодежь, Паскаль уже никто и не помнит =) Вообще модуль погоды у меня вызывает содрогание. Но если в оригинале он ещё был хоть мало-мальски вменяемый, то в Атмосфире его искорёжили совершенно непередаваемым образом.
  12. Callisto, здесь по английски http://www.lua.org/m...nual.html#5.4.1 в русском разделе сайта Lua почему-то остуствует информация о шаблонах, но в сети имеется. К примеру здесь http://luagml.ucoz.ru/doc/lua/c5.html Задача разделения такой строки может быть решена к примеру так: s = "12:34" local a,b = string.match(s, "(%d+)%d+)") print(a, В строке шаблона: "%d" - символьный класс, любая цифра "+" - предыдущий символ 1 и более раза (соответственно, 1 и более непрерывно идущих цифр) "()" - включение для поиска ":" - просто символ двоеточия Идея с шаблонами в Lua - это примерно тоже самое, что регулярные выражения. Во многом даже синтаксис совпадает, но только упрощён сильно. Можно почитать про регулярные выражения (много где описано), чтобы понять общую идею, потом сравнить с Lua и просто понять, что от них можно там использовать.
  13. SkyLoader, эта проблема решается на уровне исправления модели. Надо сделать модель так, чтобы сетка была бы раздельная для отделяемых частей и всего остального. Всегда можно найти место, где можно сделать швы на сетке незаметными. По-любому, фиксить это правками я бы не стал. Мне что-то казалось, что бокс от кости тоже скрывается. Впрочем, я не проверял.
  14. FoxFennec, извиняюсь за офтоп, но ты из какой тайги вышел? GSC уж полгода как закрылась.
  15. krovosnork, 1. на дороге неестественно новая разметка. Откуда ей взяться здесь? Разметка на любой дороге держится не больше полугода. Это же касается и видимых полос движения. Такие полосы имеются на дороге, если на ней происходит интенсивное движение и по краям дорога изнашивается видимо иначе, чем в центре, там где разметка. Если же дорога заброшена, то она приобретает равномерно разрушенное состояние по всей ширине, с трещинами, проросшим мхом и травой в случайных местах. На данном скрине же я вижу просто обычную просёлочную дорогу, весьма ухоженную. Очень неестественно для Зоны отчуждения. 2. Имело бы смысл оградку сделать более ветхой, покосить и обвалить местами. Это создало бы нужное ощущение заброшенности. Кроме того, доски чересчур светлые (если это конечно не эффект от SDK). Доски должны быть тёмно-серого цвета, какими они неизбежно становятся после пребывания на воздухе в течении нескольких лет.
  16. Malandrinus

    X-Ray extensions

    Shadows, Тебе надо найти функцию get_helicopter, там и будет адрес нужного значения. Макрос ты выбрал верно. На шестом патче адрес аргумента и соответственно заглушки в xrgame_stubs.asm будет 1054F02C.
  17. Shoker, эм.. Религия не позволяет? =) Для ТЧ уже есть такие возможности. Не помню только, делал их для оружия или для любого объекта. Однако, при желании эту правку можно откопать и задействовать. Теоретически да, если движок поддерживает не скелетную анимацию, в чём я не уверен. По моему не поддерживает. Чисто же движением костей ты такого эффекта не добьёшься. Со скрытием костей же всё просто. Одну кость скрыть, другую показать (которая дыру заткнёт), Хотя это всё конечно в теории. На практике придётся менять все стопятьсот моделей сталкеров. Вот поэтому такие фишки обычно присутствуют в играх, где тела неписей отдельно, а одежда отдельно. В движке третьего фола к примеру.
  18. Malandrinus

    X-Ray extensions

    Значит спавнишь криво.
  19. Shoker, Так при чём здесь анимации? Тебе кости надо скрывать/показывать. Вот только настраивать визуалы всех неписей - работёнка та ещё.
  20. Malandrinus

    X-Ray extensions

    Что за подскакивание?
  21. Artos, к сожалению, быстрое сохранение так не отловить.
  22. Malandrinus

    X-Ray extensions

    Shadows, здесь ты не место врезки выбираешь, а вид макроса и значение его аргумента. На основании чего они были выбраны? Артём Карпенко, я бы попробовал частично сделать это скриптами. 1. Делаешь специальную гранату с беззвучным и невидимым взрывом с визуалом и иконкой болта. 2. Следишь за её фейковой частью и при её пропадании (взрыве), спавнишь на уровне новый болт, который уже можно будет подобрать. Задачи, которые останется решить: 1. сделать так, чтобы неписи этого болта не шугались 2. заблокировать спавн в инвентарь движкового болта, что тоже потребует лезть в движок, но это уже проще, чем править движковый болт. Может даже без этого получится, если попробовать просто удалять болт из инвентаря.
  23. Viнt@rь, Скорее всего не выйдет. В Lua нет постфиксных операторов и добавить их не получится, без влезания в код компилятора. Ко всему прочему, комбинация "--" является началом комментария.
×
×
  • Создать...