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

Malandrinus

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

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

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

  • Дней в топе

    13
  • AMKoin

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

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

  1. Ray, совершенно согласен насчёт читабельности. Но я чего завёлся-то, такой код стимулирует по аналогии писать в вырожденном случае кошмарную конструкцию вида: if <лог. выр.> then return true else return false end Посему я бы написал тот фрагмент так: function has_info() local has_info = db.actor:has_info("info") if has_info then ................. end return has_info end Что в вырожденном случае (при отсутствии действия по условию) приводит к более вразумительному коду.
  2. Garry_Galler, Правильно. Ещё вариант, проверять оставшееся место перед каждым оператором записи. вопрос не по теме - как подключать в SCITE библиотеку классов? вроде require (classlib") - только куда это вписать и надо ли модуль создавать...и саму библиотечку куда лучше положить. Вписать в начале головного модуля. Библиотеку клади рядом с выполняемым файлом. А что за классы? Luabind же в SCITE недоступен.
  3. Было бы там чего изучать, особенно для вывода строк. text = string.format("%s %s %s %s %s.%s.", obj_name, verb, adjective, substantive, str, habar) Стоит проверка на запас в 180 байт. Потом пишутся все данные функцией taynik_rnd.message_save. Ты бы привёл её код, а то так не понять. Что за число 180? Какое отношение имеет к записываемым данным? Где твои 45-50 сообщений?
  4. Интересно, почему так? Реально выдаётся при следующем апдейте? Думаю, надо делать это в netspawn. По идее, что переход на другой уровень, что загрузка игры происходят одинаково. При этом актор переходит в онлайн и однократно срабатывает netspawn биндера.
  5. Ключом может быть любая переменная, кроме значения nil: числа, строки, булевские, таблицы, функции и пользовательские объекты. Вопрос некорректно поставлен. Какую-то нагрузку несёт любое шевеление. Другое дело, какую нагрузку несёт этот вариант по сравнению с каким-то другим. С чем ты его сравниваешь? Если замутили таки функцию и надо вернуть true/false, то довольно часто можно обойтись без возврата false. Если ничего не возвращать, то это эквивалентно возврату nil. А nil в свою очередь в логических выражениях однозначно интерпретируется как false (согласно синтаксису языка). Впрочем, в данном случае это будет скорее трюкачеством.
  6. Про список геймвертексов я здесь писал. Или, как верно говорят, используй ggtool.pl. Левелвертексы можно для текущего уровня перебрать с помошью функции level.vertex_position(i). только так не узнать, сколько их, и это только для текущего. Можно пробежаться по уровням и перебирать до вылета. Если совсем сильно надо, то смотрим исходники Бардака, и разбираем ручками файл level.ai нужного уровня. Только в самом деле зачем нужен список из миллионов левелвертексов? Кроме того, от мода к моду списки гейм и левел вертексов меняются. P.S.: Комрады, а зацените, какая нынче мОлодежь пошла. Не как узнать, не какой функцией, не где посмотреть... Дай ему, вынь да положь =)
  7. Garry_Galler, уф... ну давай поговорим о базовых понятиях ООП. То, что написано в файле биндера и то, что указывается в секции - это класс. Класс - это не объект, это описание объекта, тип, если угодно (хотя здесь это не совсем тип). Когда создаётся онлайновый объект, то создаётся объект класса. И к онлайновому объекту прицеплен именно объект. Потому кстати и биндер (binder), что от слова bind (привязывать, присоединять). Ещё раз: у каждого клиентского объекта свой объект биндера, даже если эти объекты одного класса. С точки зрения синтаксиса дилемма "один класс / много объектов" решается просто. У каждого метода есть скрытый первый аргумент self, в котором методу передаётся ссылка на конкретный объект. Таким образом один и тот-же метод может обслуживать множество объектов. Это достаточно типичный подход, используемый в большинстве современных языков. Таким образом self - это всегда текущий объект биндера. self.object - это соответственно клиентский объект, к которому этот биндер прицеплен. С нетпакетами ситуация такая. У каждого объекта есть буфер на 8кб, в котором объект хранит своё состояние. Это не нетпакет, а просто буфер. Нетпакет - это просто средство получать и записывать туда информацию. Сам по себе нетпакет - это обычный объект, которой можно создать и который автоматом удалится сборщиком мусора. Ещё раз, данные сохраняются в объекте, через нетпакет они просто туда передаются, для чего имеются методы класса биндера. Если уж быть корректным до конца, то в биндере на чтение используется не нетпакет, а почему-то reader. На практике терминология постоянно смешивается. Биндером называют и класс и объекты, говорят "сохранить в нетпакете", "сохранить в биндере" и т.п. Это и понятно, трудно в обычном разговоре постоянно сохранять предельную точность. По поводу стиля сохранения. Таки желательно придерживаться верной стратегии: 1. Сохранять минимум информации 2. Сохранять там, где надо. По первому пункту самая общая рекомендация - избегайте избыточности. Если конкретнее: - если есть строка, выбираемая из заранее известного набора, то лучше сохранять её номер, а не целиком строку - если можно что-то вычислить на основе другого, то лучше вычислить - для логических переменных можно использовать двоичные флажки Отдельного разговора заслуживают строки. Вообще нужда сохранять именно строки возникает не так уж часто. Между тем, как я заметил, народ почему-то весьма злоупотребляет строками. Как-то видел сохранение массива с переводом его в строку вида "a,b,c,d", сохранением в виде строки, а при чтении элементы распарсивались обратно. Ужас! Нет как правило никакой необходимости сохранять не строковые данные в виде текста. Они при этом занимают больше места и тратится существенно больше времени. Особенно при чтении как в случае с массивом выше, где фактически использовались регулярные выражения (!). Дополнительная неприятность - что место под хранение нужно заранее непредсказуемого размера, что делает невозможным предварительную оценку свободного места в буфере. Насчёт второго пункта соображения простые. Если данные относятся к конкретному объекту, то в нём и надо сохранять ("в его биндере"). Точнее здесь не скажешь. В конкретном случае надо включать мозг и думать, где и как сохранить.
  8. В данном случае индексы указывать не надо. Автонумерация от единицы и так получится. Т.е. достаточно как-то так: local funcs = { fun1, fun2, fun3, ... } Зато конструкция вида: local funcs = { [<ключ1>] = function1, [<ключ2>] = function2, [<ключ3>] = function3, ... } вполне заменяет недостающий оператор switch. Это может радикально ускорить выполнение некоторых фрагментов, если заменить этим убогие километровые списки из if - else. Что касается неподходящей темы, то я с этим не согласен. Не помню, говорил или нет, но желание было замутить здесь статейку другую по "advanced Lua", где в том числе обсуждались бы и такие вопросы. Потому что смотреть на код порой просто больно. Теми же таблицами похоже что сами разработчики научились пользоваться только в ЗП =) Добавлено через 13 мин.: Раз пошла такая пьянка. Комрады, не пишите плиз соединение нескольких строк так: res = a..b..c..d..e Это очень медленно, поскольку на каждую операцию конкатенации приходится вычисление суммарной длины и выделение памяти под новую строку. Вместо этого используйте string.format: res = string.format("%s%s%s%s%s",a,b,c,d,e) При таком способе вычисление суммарной длины и выделение новой памяти происходит всего один раз. Кроме того, статичные фрагменты можно разместить прямо в строке формата. Опять же, дополнительные возможности по форматированию. Способ первый даёт N^2 время вычисления, где N - число соединяемых строк. Способ второй - N. Регрессия производительности может быть совершенно чудовищная. Не говоря уже о фрагментации памяти. Так можно соединять и заранее неизвестное число строк. Если надо, напишу как именно.
  9. Garry_Galler, полагаю, что придётся думать о куда более серъёзной экономии, нежели 30-50%. Нетпакет актора в некоторых глобальных модах занят почти полностью. Мне просто интересно, что же там такое сохраняется такого размера. Не мог бы привести пример одного твоего сохраняемого сообщения?
  10. Garry_Galler, я имел в виду сомнительность с технической точки зрения =) Что-то явно не так, если каждая строка занимает по четверть килобайта. Даже теоретически их можно в этом случае записать всего около 30-и. Может записывать не в виде строк, а виде бинарных данных? Может что-то можно не записывать, а хранить постоянно в конфигах? Например часто можно вместо строк записывать их номера. А многие данные можно получить на ходу из других. Например по id объекта можно получить его имя, описание и пр. Значит всё это можно не хранить, а сохранить только id (два байта).
  11. Ой смотри, весь нетпакет - 8 кб. А в акторовском ещё всего до фига. Какую-то сомнительную идею ты пытаешься реализовать. Данные не в нетпакете хранятся, а в объекте. Какая разница, два уровня или десять? Главное, читать в том же порядке, что и записывал. Перед записью переменного числа элементов записываешь их количество. Вот и все секреты. Ещё раз, сохраняется не нетпакет сам по себе, а объект и вместе с ним то, что было в его нетпакет записано. В актора пишут только потому, что он всегда доступен. Ничто не мешает записывать дополнительные данные в другие объекты. Собственно в их биндерах это и делается повсеместно. Хм. Дарю идею. Сам как-то хотел сделать, но руки не доходят. Можно завести специальных объектов, которые никак в игре не участвуют, а используются только для хранения данных. Такие можно сделать на связке cse_alife_object - CGameObject. А может это был cse_alife_dynamic_object, не помню точно какой объект был минимально создаваемым. Запретить переход в онлайн, по созданию объект регистрировать, при недостаче места создавать новый, наращивая таким образом объём хранимых данных. Будет отличная альтернатива пстору актора.
  12. Malandrinus

    Моделирование в Maya

    Министр, ну это со стороны скриптов. Непосредственно костями управлять нельзя, но есть так называемые физические элементы (physics_element) и сочленения (physics_joint). Поначалу я думал, что элементы и кости - это одно и тоже. Но потом выяснил, что элементов обычно меньше, нежели костей. Могу предположить, что кости как-то в эти элементы объединяются, и в пределах одного элемента кости взаимно неподвижны. Если так, то я и хочу выяснить, где это объединение происходит. Указывается ли это где-то в модели в настройках скелета или этим занимается движок уже во время работы? Поскольку я ни макса ни майи не знаю, то даже предположить не могу ни как эти настройки могут называться, ни где могут находиться (и могут ли вообще находиться).
  13. Hagard, Ray, не понимаю, если честно, этой возни. С хедшота из почти любого приличного ствола можно почти наверняка уложить кого угодно. Монстры - это отдельный разговор, но люди в этой игре - враги вообще никакие.
  14. Garry_Galler, а держишь его горизонтально? Там в центре есть индикатор, если наклонить компас больше определённого, то его "заклинивает"
  15. Malandrinus

    Моделирование в Maya

    Комрады, мне нужна консультация по скелетам. Пытаюсь понять вот какую вещь. Когда ковыряешь физику объектов в игре скриптами, то видно, что костей много, а физических элементов и соединений существенно меньше. Хочу понять, где и как задаётся соответствие костей скелета и физических элементов/соединений. Есть ли что-то на эту тему в 3D редакторе?
  16. Давно думаю. Надпись под курсором, та что с дальностью до цели - это вполне возможно статик, как и многие другие элементы худа. Если так, то зная его идентификатор можно получить его текст и таким образом использовать встроенный дальномер. Ни у кого нет информации на эту тему?
  17. Нет возможности повесить обработчик "на нажатие". Все обработчики работают по некоторым игровым событиям, которые к нажатию на конкретную кнопку относятся только косвенно. Что касается ПНВ, то я сам не знаю, как именно это отловить. Функции с vision как правило относятся к управлению зрением неписей. Вообще для управления актором функций довольно мало. В принципе это понять можно, актор же управляется непосредственно игроком, а не скриптами. Кроме того, прослеживается принцип минимализма. Разработчики экспортировали только то, что нужно было им.
  18. Starter, по изменению fov ловишь момент прицеливания и дальше рисуешь на худе нужные бантики. касательно предыдущего обсуждения насчёт утилиты перехвата нажатий. Нашел здесь. Там же исходники. Ray, что ты имеешь в виду под "базовыми скриптами"?
  19. Monnoroch, нет, там принцип такой, что ловились нажатия клавиш в системе вообще и писались в некий *.ltx . А оттуда по апдейту актора ловились в скриптах. Вот только не могу у себя найти эту утилитку. Давно было.
  20. n6260, такая утилита для перехвата нажатий есть и очень давно. Сделана неким заграничным камрадом. Найти у себя не смог =(
  21. Vano_Santuri, По-моему никак это ни на что не повлияет. Дели или объединяй скрипты как тебе удобно. На мой взгляд, реально вызвать переполнение стека только если зациклить рекурсивный вызов. Типа такого: function fun() fun() -- сама себя вызывает до бесконечности end fun() -- здесь получишь вылет с сообщением "stack overflow" Для вылета в данном случае потребовалось 16 тыс. итераций. Я думаю, можно попытаться вызвать переполнение стека, если распаковать длинную таблицу и сунуть её как список аргументов. Но это всё нетривиальные случаи, как правило такой ситуации быть не должно.
  22. в acdc есть целая секция на предмет координат создаваемых артов. Точки из этой секции вообще где-то используются?
  23. Проще всего попробовать. Если же хочется разобраться в сути, то надо взять acdc для ЗП и посмотреть там формат нетпакета и сравнить его с форматом для ЧН. =) Стек вообще означает "стопка чего-либо". Классическая иллюстрация этого понятия - это устройство в барной стойке, куда складывают мытые тарелки. В этом случае стопка подпружинена снизу и ограничена сверху, чтобы верхняя тарелка всегда была строго в одной позиции. Смысл стека в любом его понимании - это хранилище объектов, из которых всегда доступен только последний, помещённый туда: "последний зашёл - первый вышел", "Last In - First Out", LIFO. В компьютерах, в силу фундаментальности такого принципа организации данных, стеки используются повсеместно и часто поддерживаются на уровне команд процессора. В частности, на стеке основан механизм вызова функций: адрес возврата перед вызовом пишется в стек, это позволяет после завершения работы функции вернуться в точку вызова. В стек же пишутся и аргументы функции (не всегда). У Lua свой стек, не связанный со стеком процессора (точнее потоков). Написание этого слова через "Э" или через "Е" в целом достаточно произвольно и зависит от доминирующей нормы произношения =) Москвичи больше "э"кают, питерцы чаше предпочитают более мягкие варианты с "е". Впрочем, это уже могли и законодательно устаканить. Под стек заранее выделяется память. Он заполняется в одном направлении. Когда выделенная область заканчивается - это переполнение стека. Они же без логов. Как узнаешь, могут или нет =) Вылет без лога может быть при переполнении стека процессора, но это - довольно редкая ситуация в работающем и отлаженном приложении. Переполнение стека Lua - вылет может быть запросто, но обычно в этой ситуации есть лог. Причина вылетов может быть разная. Движок игры исходно не рассчитывался на все те безобразия, что вытворяют с ним модостроители. Может и нельзя 100 аномалий спавнить, может нельзя делать это слишком часто, а возможно, где-то в скрипте просто баг. Для начала, стоит попробовать поэкспериментировать. А если не 100, а 50 аномалий? Тоже вылет?
×
×
  • Создать...