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

Справочник по функциям и классам


Рекомендуемые сообщения

Сначала в двух словах, как пользоваться механизмом выдачи заданий.
Для выдачи задания есть метод класса game_object (естественно, это должен быть актор)

void give_task(
    CGameTask* <задание>, -- подготовленный объект задания, см. далее
    int <время до истечения>, -- время от начального момента до истечения срока задания в ms
    boolean <проверять на наличие такого>) -- если true и задание с таким идентификатором уже есть, то не будет добавлено

Комментарии:


1. Нетрудно посчитать, что в 32-х разрядное целое влазит миллисекунд примерно на месяц. Соответственно - это и будет максимально возможным временем для задания.
2. Третий параметр вероятно имеет смысл использовать для разных категорий заданий. Одноразовые квестовые должны иметь параметр true, а повторяющиеся однотипные - false

Выдаём задания так:
1. Сначала надо подготовить объект типа CGameTask. Самый простой способ - воспользоваться уже готовыми заданиями, описанными в xml файлах. Для этого у класса CGameTask есть метод load
local new_task = CGameTask()
new_task:load("gar_car_graveyard_quest") -- задание "Предложить помощь Бесу"
2. Собственно выдаём задание
db.actor:give_task(new_task, 3600*1000, true) -- срок выполнения 1 час, если уже выдано, то второй раз не получим

Для получения статуса отдельной подзадачи задания есть метод класса get_task_state.
enum ETaskState get_task_state(string <идентификатор задания>, int <номер подзадачи>)
перечисление ETaskState экспортировано в виде класса task (см. далее)
Пример использования
local task_status = db.actor:get_task_state("gar_car_graveyard_quest", 0)

Для установки статуса отдельной подзадачи есть метод set_task_state:
void set_task_state(enum ETaskState <статус>, string <идентификатор задания>, int <номер подзадачи>) -- если такого задания у актера нет, то выдаст ошибку

Это всё было для уже готовых заданий. Если надо лепить задания скриптами, то необходимо использовать все возможности класса CGameTask. Далее я привожу описание классов CGameTask, вспомогательного класса SGameTaskObjective и task. Если кому это на самом деле надо, этого описания должно быть достаточно.


  Описание класса CGameTask (Показать)

  Описание класса SGameTaskObjective (Показать)

  Вспомогательный класс task с константами статуса (Показать)

Начиная с ЧН система заданий несколько изменилась. Исчезли подзадачи и соответственно перестал быть нужным класс SGameTaskObjective. Его методы по сути просто перешли в состав класса CGameTask. На мой взгляд всё стало проще, и если Вы поняли, как это работает в ТЧ, то экстраполировать это на ЧН и ЗП труда не составит.

Изменено пользователем Kirgudu
  • Спасибо 1
  • Полезно 1
  Полезный утиль (Показать)
Ссылка на комментарий

А кто-нибудь знает как определить, что актор бежит?

 

пока нашел способ определения по значению accuracy() но приходится подгонять его под каждое оружие

метод сравнения координат актора "до" и "после" почему-то выдает резкие скачки значений, потому не подходит

i-igroman.ru - Мой, принципиально новый сайт о компьютерных играх

Ссылка на комментарий

lekzd,

можно попытаться по разнице между position и center. Это типа по наклону туловища =) Но там тоже нестабильные значения.

Вообще-то по скорости не так уж и плохо работает. Если учесть, что апдейты идут нерегулярно и вычислять скорость по настоящему, т.е. учитывая параметр delta, то точность повышается. Также вроде как лучше вычислять скорость только с учётом координат xz, т.е. игнорировать вертикальную компоненту. Кроме того, можно ввести фильтрацию шума - усреднение по нескольким точкам. У меня усреднение по трём дало достаточно различимую картину: стоит, идёт, бежит. Но иногда таки бывают выбросы. По пяти точкам - различие практически идеальное. Хотя и появляется некоторая микроскопическая задержка, связанная с размазыванием переходов.

Вопрос ещё, для чего это надо. Если скажем надо просто отобразить состояние бега на худе, то и так вполне сойдёт.

  Полезный утиль (Показать)
Ссылка на комментарий

malandrinus, я сделал полностью динамический ХУД и скрываю его во время бега

при резких скачках он начинает "моргать" (значения резко скачут), что приводит к падению ФПС

 

можешь привести код проверки по трем точкам? (я делал код проверки по x z + усреднение значений по двум точкам во времени)

i-igroman.ru - Мой, принципиально новый сайт о компьютерных играх

Ссылка на комментарий

Введение

  Показать


Итак. Все игровые сущности (сталкеры, монстры, предметы и пр.) в общем случае существуют одновременно на двух сторонах - на сервере и на клиенте. На каждой стороне для этого есть соответствующие классы. На серверной - это классы, имя которых начинается на "cse". С некоторыми поправками можно считать, что все серверные классы происходят от cse_abstract. На клиентской стороне есть соответствующая иерархия классов. Можно считать, что все они происходят от CGameObject. На клиентской стороне есть ещё и game_object, который также является интерфейсом к клиентским объектам, причём основным интерфейсом. Его описание уже начато, но оно далеко от завершения.

Классы как серверные, так и клиентские образуют иерархию наследования классов. На самом примитивном уровне можно считать, что наследование означает включение всех членов базового класса (т.е. свойств и методов) в производный класс. В свою очередь это означает, что нет необходимости описывать унаследованные члены для всех производных классов, достаточно это сделать один раз для базового. Кроме того я ввожу важное соглашение для описания классов: я не буду приводить полный список членов класса для каждого из них, а только список методов и свойств, которые добавляет конкретный класс сверх унаследованных. Поэтому, если по описанию в классе нет ничего, то смотрите на классы от которых он унаследован и смотрите список их методов и список методов их базовых классов и т.д. Я вынужден так сделать во-первых в силу ограничения форума, во вторых для убирания избыточности при описании. Я также буду пользоваться спойлерами: после описания класса будет идти спойлер с его производными классами, в них спойлеры с их производными и т.д. (наподобие матрёшки =)

Начнём с серверных.
Можно обратить внимание, что имеется некоторое количество базовых классов и интерфейсов, которые вообще не содержат никаких методов или свойств. Наследование от них не даёт конкретной информации о свойствах серверного класса, но парадоксальным образом может дать некоторые догадки о применимости методов game_object. Вот список этих базовых интерфейсов:

Базовые интерфейсы

  Показать

 

Несколько предваряющих комментариев к дальнейшему материалу. 

  Показать


Вся иерархия серверных классов

  Показать

 

Изменено пользователем Kirgudu
  Полезный утиль (Показать)
Ссылка на комментарий

Полагаю, красивая картинка никому не помешает. Вот вам диаграмма серверных классов с высоты птичьего полёта =) Обращаю внимание на нотацию записи: большая пустая стрелка означает отношение обобщения (или наследования иными словами) и направлена от унаследованного класса к базовому. Включение абстрактного интерфейса обозначается стрелкой с кружочком и указанием, какой интерфейс наследуется. Это сокращённая форма записи, позволяющая избавиться от нагромождения линий и лучше понять основную линию наследования.

  Генеалогия серверных классов (Показать)
Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий

Просто наблюдение:

Разница между значениями game.time() и game.get_game_time()" - заметил, что при старте новых игр она каждый раз разная, и где-то, после 40млн.милисекунд, при рестарте счётчика, её значение изменяется...

 

  Цитата
как ты высчитываешь разницу?
Стартовал новую игру, получал game.time() и game.get_game_time(), переводил game.get_game_time() в мсек, вычитал и смотрел разницу.

  Цитата
И какой рестарт счётчика ты имеешь в виду? Тот, что раз в месяц?
Разница, была статична до того как, через какое-то игровое время, значение game.time() сбросилось и продолжило счёт с нуля, разница то-же пересчиталась и стала другой. Вот насчёт 40 млн... это я визуально запомнил - это может и не так быть, но срок был, в роде больше месяца, намного.

 

Надо повторить эксперимент, а то вдруг чего не так делал... перепроверю.

Но то, что game.time() обнулялась - это точно.

Изменено пользователем 7.9

всё легко

Ссылка на комментарий

7.9,

всё верно, только не 40 млн., а 4 мрд., точнее максимальное 32-х разрядное беззнаковое целое:

4294967295 что в миллисекундах составляет примерно 1193 часа, т.е. 49 дней.

Это известная проблема: после примерно месяца игрового времени часть функций, связанных с использованием этого счётчика, начинают работать неправильно. Вроде как это даже лечили. Хотя если этот счётчик используется не только скриптами, но и движком, то всё не вылечить.

Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий

Разбираем систему клиентских классов.

Сначала немного лирики.

  Показать


Довольно лирики. Далее представлена система клиентских классов. Используются те-же соглашения, что и раньше: конструктор не показан, если класс не добавляет своих методов, то показан одной строкой.

 

Иерархия клиентских классов

Сперва базовые интерфейсы. Их не так много, как у серверных. 

  Показать

 

Все остальные классы имеют своим предком CGameObject

Классы, производные от CGameObject

  Показать

Рисовать картинку с иерархией наследования смысла нет, поскольку и так всё довольно очевидно. За исключением малого числа классов остальные к CGameObject ничего не добавляют. Соответственно и описывать нечего. Названия классов более или менее говорят о том, для каких объектов они предназначены. Где мог, указал точные сигнатуры функций (CCar, CHelicopter и hanging_lamp). Для новых классов и методов по сравнению с ТЧ такой информации к сожалению нет.

Несколько рассуждений на тему взаимодействия серверного и клиентского объектов. Попробуем рассуждать логически. Есть сервер, есть клиент. Это в общем случае разные компьютеры. Каким может быть взаимодействие объектов, находящихся по разную сторону сети? Могут ли они, к примеру, вызывать методы друг друга, или непосредственно читать данные своего "напарника"? Очевидно нет. Моё мнение такое, что их взаимодействие сводится в основном к посылке данных друг другу. При этом, данные посылаются "пачкой", т.е. обо всём состоянии сразу. То, что я наблюдал, выглядит так: при переходе в онлайн создаётся клиентский объект, серверный его инициализирует, посылая ему при создании нетпакет. Этот момент можно отловить в биндере клиентского класса. Все дальнейшие движения происходят от клиентского объекта к серверному. Это означает, что периодически клиентский затирает данные серверного. Точные моменты, когда это происходит, периодичность, а также механизм передачи данных мне лично понять пока не удалось. По крайней мере на серверной стороне ничего не видно, просто тихо меняются данные, и понять, когда это происходит, крайне непросто.
Однако некоторые выводы таки можно сделать. Если взаимодействие классов примерно такое, как я здесь предположил, то совместимость классов определяется совместимостью бинарных данных, которые они друг другу посылают. Ну в общем классы должны друг другу соответствовать, хотя, как далее будет видно, это правило на практике (очень редко) нарушается. Если не забыли ещё, то зарегистрированные пары классов задаются идентификаторами класса. В файлах конфигурации (в секциях объектов) этим идентификаторам соответствует параметр class. В скриптах - это один из членов clsid. В движке уже зарегистрированы соответствующие пары классов, и вы можете добавлять свои пары с помощью класса object_factory. Я это всё описывал 
здесь.

Далее я привожу таблицу соответствия классов. Для полноты картины в ней указаны классы, которые не экспортированы в Lua. Если класс не экспортирован, то это означает, что вам не удастся зарегистрировать на его основе свою пару классов. Однако это не мешает (теоретически) создавать объекты этого класса при условии, что имеется и известен его идентификатор.
Приведённая таблица собрана из разных источников, в том числе основана на примерах регистрации классов из игры. Видно, что иногда клиентский класс использует в качестве "напарника" серверный, который является базовым для своего "родного" серверного. Видимо, это технически в норме вещей и так можно поступать и нам. Из этого ряда выбивается CZombie, для которого вроде бы родным должен быть серверный класс cse_alife_monster_zombie, а регистрируют его с cse_alife_monster_base. Это вроде как нарушает вышеописанную логику, поскольку cse_alife_monster_base не является базовым для cse_alife_monster_zombie. С другой стороны, он так зарегистрирован в самом движке. Возможно cse_alife_monster_zombie попросту не задействован и никакого отношения к CZombie на самом деле не имеет. 


Таблица соответствия серверных и клиентских классов

  Показать
Изменено пользователем Murarius
  Полезный утиль (Показать)
Ссылка на комментарий
  malandrinus писал(а):
Вот этот залипон со счётчиком времени - это совершенно типичный пример. И ведь игра заведомо создавалась, как шутер с элементами РПГ. Т.е. подразумевалось, что игрок будет исследовать локации, возвращаться на них, чтобы доделать квесты и прочее в этом роде. Учитывая дефолтовое соотношение игрового времени к реальному десять (!) 49 дней с легкостью превращаются всего в 5 дней реального игрового времени. Пять дней?! Для РПГ?! Смешно даже. И что мешало разрабам просто взять и посчитать, на сколько хватит этого счётчика?

В движке в классе CTime 64х-разрядный счетчик и считает он нормально. Вообще вокруг этой проблемы слишком много шума. В оригинальной игре я ее не встречал. Видел только в АМК моде, но там использовали функцию level.get_time_days(), которая возвращает день месяца. Отсюда и пошла проблема 1 июня. Когда я заменил на использование CTime, то стало работать и после этой даты(заменил только для выброса, в остальных местах не менял).

 

Изменено пользователем malandrinus
Ссылка на комментарий

malandrinus, чего-то я это нигде не встречал, а что это вообще такое?

cse_alife_item_weapon_auto_shotgun     |  CWeaponAutomaticShotgun

Как-то можно штуцер сделать (один ствол нарезной, второй гладкоствол)? Почему-то через подствольник W_GLAUNC не получается :(

 

Изменено пользователем malandrinus
Цензура ограничивает творчество © by me
Ссылка на комментарий

dimos,

Это «Отбойник» - автоматический дробовик из ЗП. Секция wpn_protecta в файле configs\weapons\w_protecta.ltx.

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

W_GLAUNC - это вообще никак не поможет, поскольку это объект подствольника, а все аддоны - это просто инвентарные предметы. Они не стреляют, стреляют стволы. При надевании аддона сам объект аддона исчезает, а у ствола просто устанавливается соответствующий флажок.

Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий
malandrinus, пардон, все время сужу по ТЧ, а там этого класса нет. Кстати, может как-то сделать небольшой пост по отличиям ЗП от предыдущих частей, хотя бы после выхода АМК ЗП? :) Или добавить коменты к предыдущим статьям, хотя первую страницу редко кто читает... Например, тот же класс CCar, в ЗП его уже нет. Изменено пользователем malandrinus
Цензура ограничивает творчество © by me
Ссылка на комментарий
  Цитата
Например, тот же класс CCar, в ЗП его уже нет.
Да есть он там! Кто сказал что нет? Даже в lua_help остался. Можно создать машину, хотя и не получается на ней поездить. Изменено пользователем malandrinus
  Полезный утиль (Показать)
Ссылка на комментарий

Замеченные мной отличия скриптов ЗП от ТЧ (предлагаю развивать тему):

  Диалоговые окна (Показать)

 

  Прочее (Показать)

 

Изменено пользователем Kirgudu

i-igroman.ru - Мой, принципиально новый сайт о компьютерных играх

Ссылка на комментарий
  _g.script (Показать)

i-igroman.ru - Мой, принципиально новый сайт о компьютерных играх

Ссылка на комментарий

Вот такой вопрос, если ответите, то буду очень признателен:

 

1)Есть функция нет-пакета для спавна аномалий, за авторством Шокера, делалась для ЧН, подходит ли для ЗП? Если нет , что поправить?

 

  Функция (Показать)

Что-то кончается, что-то начинается...

Ссылка на комментарий

1) врятли чтото изменилось...

2) ну я не могу сказать по научному,но это чтото типа выделенной памяти для некоего списка.

3) приводит к тому,что данное записывается в него а там нет места - ну и вылет.

4) врятли.есть вылеты stack overflow

5) а почему нет?можно.

 

===

 

в качестве коммента

  Цитата
заспавненные нет-пакетом

Это что за бред?

Спавнишь методом alife():create()

А потом переписываешь пакет есму с помощью обьекта класса net_packet()

 

6)попробуй заспавнил,удалил,сэйв,лоад,заспавнил,удалил.... и т.п.

Никогда не вылетишь :)

Изменено пользователем Monnoroch
Ссылка на комментарий

Monnoroch, Все, решил свою проблему, вылет был из-за того, я так полагаю, что слишком много действий в один момент. Сделал по умному, разбил эти 100 аномалий на 10 циклов, и поставил на таймер, теперь через каждые 2 минуты спавнится цикл аномалий из 10 штук. класно Даже не зависает ни на капельку.

 

Немнго инфы для людей, возможно к лассам она не имеет никакого значения, но вот :

 

1)Допустим вы хотите заспавнить предмет\монстра \непися или еще чего в случайно рандомном месте , но не знаете как.Вот пример простой функции:

function random_place_spawn()
lv_new = math.random(1845795) -- ( количество левелвертесов на уровне, или иное значение, если надо сузить область)          
pos_new = level.vertex_position(lv_new)  --(этот метод находит вершины вертекса)
alife():create("cекция объекта",vector():set(pos_new.x,pos_new.y,pos_new.z),lv_new,0)
end

0 - это геймвертекс затона, т.е общий, но работает для всех точек.

317 - Юпитер

666 - Припять

Изменено пользователем Murarius
  • Нравится 1

Что-то кончается, что-то начинается...

Ссылка на комментарий
  Vano_Santuri писал(а):
1)Есть функция нет-пакета для спавна аномалий, за авторством Шокера, делалась для ЧН, подходит ли для ЗП? Если нет , что поправить?
Проще всего попробовать. Если же хочется разобраться в сути, то надо взять acdc для ЗП и посмотреть там формат нетпакета и сравнить его с форматом для ЧН.

  Цитата
2)Что такое стэки(стеки)?
=) Стек вообще означает "стопка чего-либо". Классическая иллюстрация этого понятия - это устройство в барной стойке, куда складывают мытые тарелки. В этом случае стопка подпружинена снизу и ограничена сверху, чтобы верхняя тарелка всегда была строго в одной позиции. Смысл стека в любом его понимании - это хранилище объектов, из которых всегда доступен только последний, помещённый туда: "последний зашёл - первый вышел", "Last In - First Out", LIFO. В компьютерах, в силу фундаментальности такого принципа организации данных, стеки используются повсеместно и часто поддерживаются на уровне команд процессора. В частности, на стеке основан механизм вызова функций: адрес возврата перед вызовом пишется в стек, это позволяет после завершения работы функции вернуться в точку вызова. В стек же пишутся и аргументы функции (не всегда). У Lua свой стек, не связанный со стеком процессора (точнее потоков).

Написание этого слова через "Э" или через "Е" в целом достаточно произвольно и зависит от доминирующей нормы произношения =) Москвичи больше "э"кают, питерцы чаше предпочитают более мягкие варианты с "е". Впрочем, это уже могли и законодательно устаканить.

  Цитата
3)Что такое перпелолнение стэков(стеков)?
Под стек заранее выделяется память. Он заполняется в одном направлении. Когда выделенная область заканчивается - это переполнение стека.

  Цитата
4)К чему приводит переполнение стэков(стеков)? Вылеты без логов могут быть вызваны переполнением стэков(стеков)?
Они же без логов. Как узнаешь, могут или нет =) Вылет без лога может быть при переполнении стека процессора, но это - довольно редкая ситуация в работающем и отлаженном приложении. Переполнение стека Lua - вылет может быть запросто, но обычно в этой ситуации есть лог.

  Цитата
6)Довольно простой пример, заспавнил 100 аномалий
Причина вылетов может быть разная. Движок игры исходно не рассчитывался на все те безобразия, что вытворяют с ним модостроители. Может и нельзя 100 аномалий спавнить, может нельзя делать это слишком часто, а возможно, где-то в скрипте просто баг.

Для начала, стоит попробовать поэкспериментировать. А если не 100, а 50 аномалий? Тоже вылет?

 

  Полезный утиль (Показать)
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Куратор(ы) темы:

×
×
  • Создать...