Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
  • Нужна помощь?

    Создайте тему в соответствующем разделе
    Не нужно писать всё в чат!
  • Загляните на торговую площадку

    Там вы можете купить
    всё что касается игровых серверов
  • Не хотите бан?

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок!
  • Продаёте или покупаете?

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной

Таблица лидеров


Популярные публикации

Отображаются публикации с наибольшей репутацией на 01/12/21 в Сообщения

  1. 1 балл
    123new

    [Enscript] Учимся основам скриптинга

    И снова здравствуйте, товарищи и коллеги! Уже не один день наблюдаю среди многих из читающих такую проблему, как непонимание того, что написано в том или ином гайде, скрипте, теме форума по DayZ Standalone. А понимать бы это все это ой как бы не плохо было бы, да, товарищи? Ну хотя бы так, для себя, для осознания происходящего и упрощения своей жизни. Не все же за вас делать постоянно, как считаете? Что же, решил я вот для вас завести такую темку, полезную. В ней мы не будем рассматривать установку чего-либо или сборку мода. Мы попробуем разобраться в основах языка игры, а именно - написании своего кода, чтении кода игры, данного разработчиком, или чужим модом в мастерской. Разумеется, надеюсь я и на вашу бескорыстную помощь и поддержку, а также на помощь знатоков и экспертов скриптинга игры, ведь один я не справлюсь в написании этой безмерно полезной для многих и большой темы. А помощь ой как понадобится, чувствую затылком. Ну ладно, утомил я вас, начнем, пожалуй, согласны? Оговорюсь сразу, в данной теме мы затронем лишь скриптовую составляющую игры. Т.е. вопросы изменения модов, игры, создания собственных интерфейсов, игровых вещей и прочего освещаться не будут. Темы к ознакомлению, схожие с данным материалом: https://s-platoon.ru/topic/8622-enscript-delaem-skript-dlya-moda-i-osnovnye-principy-skriptinga-modov/ https://s-platoon.ru/topic/7838-sozdaem-svoy-servernyy-mod-dayz-14-to-discontined https://s-platoon.ru/topic/8859-enscript-rodnye-funkcii-v-kode-igry-opisanie-nahozhdenie/ Официальная документация, связанная с данным материалом (спасибо BorizzK? https://community.bistudio.com/wiki/DayZ:Enforce_Script_Syntax https://community.bistudio.com/wiki/Category:DayZ:Editing Начнем мы, пожалуй, с общего. Введение. Скрипты. Скрипты - важная часть функционирования игры, создания модов и модификации как игры, так и сервера. Они позволяют делать чудные модификации, создавать новые опции, настраивать или изменять в игре по своей задумке практически любой аспект и функционал, заданный разработчиками, дополнять его и разнообразить. Алгоритм Ваша первая задача при написании скриптов - определить, какие шаги надо предпринять, чтобы решить какую-либо проблему. Последовательность таких шагов - это и будет алгоритм. Например, намерение - передать другу ваш рюкзак. Значит необходимо выполнить следующие действия: Но тут у нас встает вопрос - игрок же вызывает какое-то меню или опцию, которая будет выполнять данные действия. Как это реализовать? Ведь игра - это лишь набор комманд, которые выполняются по одной за раз, как правильно объединить все и сделать корректно? Сделать это все можно именно посредством скриптинга в данной игре с использованием скриптов. Интерпретатор Когда вы составили алгоритм, вам нужно что-то, что может его исполнить. У нас есть компьютерная игра, которая может это сделать. В игре есть игроки, объекты которые могут выполнять те или иные действия, например, получение данных, создание объектов, открытие дверей и т.п. Все имеет свою комманду и результат выполнения. Иными словами, игра сама интерпретирует ваши скрипты и их код в рабочий вид в игре. Исходный код (Скрипт) Исходный код (скрипт) - это алгоритм, написанный на каком-либо языке программирования, который преобразуется в машинный код программы и будет выполнен в том или ином случае. В случае в нашей игрой это код, который игра преобразует в понятные для нее комманды и выполняет их. Скриптинг Скриптинг - какие-либо действия по написанию скриптов для своих работ\модов\игры. Скриптинг в DayZ в основном основывается на том, что уже имеется в игре. Т.е. на базовом функционале игры, который задан разработчиком. В DayZ вся скриптовая часть, написанная авторами игры, располагается в файлике "scripts.pbo" в папке "dta", который мы можем распаковать через "PBO Manager", например, и поглядеть. Любые скрипты могут содержать как набор из функций, так и набор из разных классов с функциями, которые могут вам понадобиться. Enforce Script Enforce Script (EnScript по простому)- это язык сценариев (интерпретации скриптинга), разработанный для движка игры DayZ "enforce Engine" компанией Bohemia Interactive Studio . Все скрипты EnScript, основные игровые логики находятся в "scripts.pbo" в папке "dta" каталога "DayZ" или "DayZ Server". Именно этот файл и будет нам полезен для выяснения того, как работают некоторые вещи (пока, наконец, не появится достойная ссылка на API от разработчиков игра, будь они прокляты). Основные принципы скриптинга на EnScript: Любая комманда, строка в функции должна завершаться на ; (точку с запятой) Тело любой функции/класса/структуры должно быть заключено в {} (фигурные скобки) Язык крайне чувствителен к регистру, т.е. MyPeremennaya и Myperemennaya будут 2 разными объектами для игры. Язык, крайне схожий с синтаксисом и коммандами C++, C# и JavaScript, для тех, кто знает эти языки хотя бы на любительском уровне, работать и писать свои скрипты будет проще в разы Структура скриптовой части игры Распаковав "scripts.pbo" (файл есть в клиенте игры и сервере, он одинаковый) мы увидим несколько папок, таких как "1_Core", "2_GameLib", "3_Game", "4_World", "5_Mission", "data", "editor" а также файлики "$PREFIX$", "$PRODUCT$","$VERSION$","config.bin","profile_fixed.cfg", "staticDefinesDoc.c". Из того, что мне известно, и что нам пригодится при написании скриптов, я отмечу лишь файлик "config.bin", который составляет основную конфигурацию pbo-файла и включенных в него файлов скриптов (по нему 'компилируются' при запуске игры в скрипты в определенные разделы кода запуска игры). А также папки "1_Core", "2_GameLib", "3_Game", "4_World", "5_Mission". Сам "config.bin" разбирать мы не будем, это сделано уже ранее в теме вот этой. Каждая из указанных ранее папок обозначает раздел инициализации кода игры. Например, в "1_Core", "2_GameLib" подгружается основной синтаксис всех функций и переменных игры (то как они будут объявляться в коде, вызываться, какие значения возвращать и принимать). В "3_Game" основной функционал самой игры, обозначающий используемые классы и базовые функции этих классов. В "4_World" все остальные классы, функции и параметры, которые будут исполняться в игре в зависимости от того, какие объекты окружения будут в ней будут и как будут функционировать. В "5_Mission" будет описываться функционал, относящийся к экранам загрузки, меню, их действиям и вызовам. На основе этих разделов и строится основной принцип скриптинга любого мода и функционирования игры в целом. Если вы откроете любой из модов, который имеет хотя бы 1 скрипт, увидите часть этой структуры. Основные разделы скриптов также взаимодействуют друг с другом, но только в порядке, в котором они выполняются и описываются. Например, из "5_Mission" вы можете вызывать классы и функции, описанные в "4_World", а из "4_World" вызвать функции в "5_Mission" не получится, поскольку игра их еще не знает на том этапе запуска и 'компиляции кода скрипта'. Функции Функции - это набор команд (действий) и параметров(переменных). Для ее вызова используется стандартный формат вида: {имя функции}({параметры функции}); Тело любой функции/класса/структуры должно быть заключено в "{}" (фигурные скобки) Функции могут быть как заданные разработчиками игры в каких-либо классах, так и написанные вами вручную собственные. Иногда для ее вызова хватает лишь одной лишь команды, например "MyFunction();". Но чаще в синтаксисе вызова функции присутствует один и более параметров, например "MyFunction("my text");" . Параметры функции могут не содержать значений, а могут иметь 1 или несколько значений, разделенных запятой, например: void MyFunction(int MyChislo, string text1, text2, bool value); У каждой команды может быть свой список данных, которые она может использовать в своем выполнении(например, как было в последнем примере), а также может быть и список данных, которые она вернет. Будут ли эти данные требоваться от функции зависит от автора, который эту функцию пишет (т.е. от разработчиков игры, если это скрипт родной игры, или от вас, если этот скрипт вы пишете сами) Функции с возвращаемыми данными (имеют тип значения, который они возвращают) могут вызываться как вот так: int chislo = MyFunction("my text"); т.е. переменная chislo пример значение, которое функция возвратила либо так: MyFunction("my text"); т.е. функция вернет значение, но оно не будет записано, и не будет использоваться далее. Функции без возврата значений (имеют тип void) могут вызываться только вот так: MyFunction("my text"); Функции могут иметь несколько типов. Например, void MyFunction() { } функция без возврата значения. А функция int MyFunction() возвратит значение типа int (число). Соответственно, функции без возврата значений будут содержать лишь код своих вычислений, а функции с возвратом обязаны иметь комменду return {значение} . Пример функции без возврата значений и принимаемых переменных: void MyFunction() { Print(" ---TEST--- "); } Функция запишет в script.log текст: " ---TEST--- " Пример вызова в коде: MyFunction(); Пример функции с возвратом значений и принимаемыми переменными: string MyFunction(string MyText) { Print(" ---TEST--- " + MyText); return "[" + MyText + "]"; } Пример вызова в коде: string MyTXT1 = MyFunction("TEXT FOR TEST"); Функция запишет в script.log текст: " ---TEST--- TEXT FOR TEST " и запишет в переменную MyTXT1 значение [MyText] Параметров, которые могут передаваться в функцию, может быть несколько, но не рекоммендую их делать более 10. Переменные и их типы Переменные - это типы данных, используемые в коде скриптов игры. Типы переменных обозначаются классами, заданными в игре. Это могут быть как заданные разработчиками поумолчанию типы данных, так и собственные классы, написанные вами. Обозначаются переменные общим видом так: {тип переменной} {название переменной} Строка с обозначением любой переменной или заданием ее значением должно быть закончено точной с запятой на конце! Например: int chislo, string text, bool value; или string text = "TEST"; Каждый тип означает, какие типы данных может принимать данная переменная, и какой объем в памяти игры она займет. Базовое количество типов схоже с c++ и c#, но есть и типы, обозначаемые заданными классами в игре. Стоит понимать, что объявленная 1 раз переменная в функции или классе не может быть объявлена в ней же еще раз, но ей может быть присвоено новое значение, например : void MyFunction() { string myperemennaya="text1"; // тут какие-то вычисления myperemennaya="text2"; } Список используемых типов переменных в игре можно прочитать тут (на немецком): https://germandayz.de/forum/thread/19551-guide-dayz-standalone-scripting-enforce-scripting/ Остальные имеют стандартный тип, используемый в том же с++ и c# Модификаторы функций и переменных. Также, переменные могут иметь модификаторы доступности данных в функциях. Например: public: делает переменную открытой к доступу в других функциях private: делает переменную закрытой к доступу в других функциях protected: ограничивает доступ к переменной только для дружественных и дочерних классов. static - переменная, которая сохраняется в памяти игры даже после удаления экземпляра функции (класса) или переменной из памяти (как в C++). native - Функция или переменная, реализованная игровым движком, не может быть перезаписана. В исходном коде движка такие функции отмечены со смещением. Невозможно изменить модами и сприптами, только использовать их сами. ref - ссылка на свой тип класса или переменной, ref - сокр. referal, т.е. ссылка в переводе Модификаторы также описаны по ссылке выше, и могут быть использованы не только в переменных, но и в функциях игры! Классы Классы - это структуры, которые могут содержать определенные функции и переменные, заданные автором скрипта. У классов может быть много функций, переменных, а каждый класс в свою очередь может быть задан и записан в отдельные переменные по нескольку раз. Т.е. это своего рода свой тип переменной, которая может содержать свои данные внутри себя. Отдельная переменная своего класса или одного из классов игры (например Playerbase) воспринимается как единичный некий экземпляр-объект данного класса, и чем больше таких переменных, тем больше экземпляров одного и того же класса существует в памяти игры. Например: PlayerBase player = NULL; Также, в классах можно обращаться к переменным и функциям, находящимся внутри классов через символ точки (это как вызов и получение результата функции или переменной). Т.е. для экземпляра класса: class MyClass { string MyText = ""; int Chislo = 0; void MyFunction() { Prnt("TEST"); } } ref MyClass Peremennaya = new ref MyClass(); создается переменная, и ее можно вызывать так: string MyResult = Peremennaya.MyText; и значение My Text будет записано в MyResult. Также можно и вызвать функцию или результат ее выполнения (если функция возвращает значение): Peremennaya.MyFunction() выполнит запись в script.log текста TEST. Переменные, объявляемые вне функций в классе одном будут доступны во всех функциях этого класса. Но переменные, заданные в классе, будут индивидуальны для каждого экземпляра этого класса. Т.е. если мы создаем свой класс, например, такого содержания: class MyClass { string MyText = ""; int Chislo = 0; } затем создаем экземпляры этого класса в памяти игры, коммандами ref MyClass Peremennaya = new ref MyClass(); ref MyClass Peremennaya2 = new ref MyClass(); то у Peremennaya и у Peremennaya2 будут свои данные в MyText и Choislo, не связанные между собой: Peremennaya.Text = "MyText1"; Peremennaya.Chislo = 2; Print("Peremennaya.Text = " + Peremennaya2.Text + " Peremennaya.Chislo = " + Peremennaya.Chislo.ToString()); Print("Peremennaya2.Text = " + Peremennaya2.Text + " Peremennaya2.Chislo = " + Peremennaya2.Chislo.ToString()); То мы получим в scriptlog: "Peremennaya.Text = Peremennaya.Text = MyText1 Peremennaya.Chislo = 2" "Peremennaya2.Text = Peremennaya2.Text = Peremennaya2.Chislo = 0" Т.е. в Peremennaya2.Text будет пусто. Обязательно для созданных собственных классов переменных указание ссылочности типов - ref (ref - сокр. referal, т.е. ссылка в переводе) - от этого зависит доступность данных в классах и функциях. Также, из классов можно вызывать и функции, и обращаться к переменным. Разумеется, если они не защищены функцией или модификатором. Например, создадим класс: Class ClassTest { string MyText1 = "123"; private string MyText2 = "456"; void MyFunction1 (string text) { string MyText3 = "789"; Print("!!!Used MyFunction:" + text); } int MyFunction2 () { return 2; } } и создадим экземпляр данного класса, и попробуем к нему обратиться: ref ClassTest Peremennaya3 = new ref ClassTest(); Print("Text1 = " + Peremennaya3.Text1); // В script.log будет Text1 = 123 Print("Text2 = " + Peremennaya3.Text2); // не запустится игра, так как модификатор private не позволит обратиться к переменной внутри класса Print("Text3 = " + Peremennaya3.MyFunction1 ("TEXT")); // В script.log будет Text3 = !!!Used MyFunction:TEXT Peremennaya3.MyFunction2(); // Выолнит функцию MyFunction2 и возвратит значение 2, но оно не будет записано А вот MyText3 из MyFunction1 не получить, так как она содержится внутри функции в классе. Моддинг Классов Классы, в свою очередь, можно менять модами, если они не являются 'нативными', либо не защищены движком игры разработчиков от изменений. Для этого применяют приписку "Modded" перед именем класса с сохранением его имени, например: Modded class PlayerBase { } Моддинг Функций в классах Функции в классах также можно перезаписывать. Для этого используется модификатор "override" перед тем, как задать эту функцию, а в теле самой этой функции можно (и крайне рекоммендуется, но не обязательно) использовать вызов "super." с дальнейшим вызовом этой функции и передачей оригинальных параметров функции. Например: Modded class PlayerBase { override void OnConnect() { Print("Test1"); // Эта строка выполнится до вызова оригинальной функции super.OnConnect(); // вызов оригинальной функции с сохранением ее параметров Print("Test2"); // Эта строка выполнится после вызова оригинальной функции } override string GetPlayerClass() { string returned_original = super.GetPlayerClass(); // вызов оригинальной функции с сохранением ее параметров и значения в переменную if(returned_original == "Bad Type") // Проверка значения { returned_original = "Good Type"; // Замена значения на нужное нам } return returned_original; // Возврат значения функцией } override void EEKilled( Object killer ) { super.EEKilled( killer ); // вызов оригинальной функции с сохранением ее параметров Print("Test3"); // Эта строка выполнится после вызова оригинальной функции } } Как видим, функции перепишутся с вызовом оригинального значения и допиской нужных или коррекцией. Можно делать и так, но крайне не рекоммендуется: Modded class PlayerBase { override void OnConnect() { Print("Test1"); // Эта строка выполнится до вызова оригинальной функции Print("Test2"); // Эта строка выполнится после вызова оригинальной функции } } Но в таком случае, если утеряно оригинальное выполнение кода игры и наследование функций, игра/сервер могут сломаться. Да и моды, которые параллельно с вашим, будут использовать эту функцию, могут перестать работать. Моддинг и скриптинг - Разница? Собственно, если вы осилили все. что описано выше, вы освоили базовую часть скриптинга в данной игре, а значит вас можно поздравить: Теперь вы готовы к написанию собственных скриптов и модов! Самой по себе разницы между скриптами и модами нету. Скрипты - это составляющая большинства современных модов в DayZ, т.е. непосредственная часть мода. Те же самые скрипты могут быть и в mpmissions и в моде, но с одной разницей - то что есть в mpmissions может быть в подключено в моде, а то что подключено в моде не всегда может быть подключено в mpmissions. А смысл как раз в том, что игра загружает скрипты последовательно, т.е. сначала оригинальный код игры с dta, потом моды, и только потом mpmission. Сама же "Mpmission" является частью, заданной в классе "5_Mission" в оригинальных скриптах игры, и делится на 2 файла в зависимости от типа запускаемой игры. Для клиента игры это "missionGameplay.c" а для сервера это "missionServer.c", откуда уже и читаем mpmission сервера. Иными словами, на момент чтения mpmission у нас по сути уже считаны и организованы все структуры разделов кода игры, и доступа к изменениям кодов и классов в "mpmissions" у нас нет. Т.е. то, что вносится в Mpmissions можно вносить в свой мод, но никак не наоборот. Сами же скрипты по своей стркутуре и особенностям такие же. Примечание: Что же касается модификаторов, типов переменных, функций, классов, используемых в игре в скриптах и модах, можно пока почитать вот тут на немецком: https://germandayz.de/forum/thread/19551-guide-dayz-standalone-scripting-enforce-scripting/ Позже будем пытаться создавать свою тему с данным описанием Что касается информации о родных функциях и классах, используемых в игре и на сервере - этой информации найти не смог. Но ее вы можете найти сами так: распаковываем весь scripts.pbo в папку, запускаем Notepad и используем поиск в папке по тексту (Ctrl+F вкладка №3), ищем по кусочкам нужных фраз на английском и смотрим как называется функция, ее расположение в классе. Также, предлагаю всем, кто заинтересован в облегчении поиска информации о таких функциях, помочь друг другу и составить этот список самим в вот этой теме на форуме: Поиск по форуму поможет остальным найти интересующую нас информацию ?
  2. 1 балл
    Друзья, некоторое время ранее я в теме вот этой описывал создание как своего серверного мода, так и самой базовой общей структуры любого клиент-серверного мода с нуля. Но я не затрагивал момент о написании собственных скриптов для такого мода. Собственно, этот момент в данной теме и рассмотрим. Данная тема размещена в разделе не гайдов, а описания по игре, так как она носит более информативный характер, нежели гайд. Всем новичкам. пытающимся создать свой сервер советую прочесть. эксперты могут смело проходить мимо. едва-ли что-то новое узнаете. Предупреждаю, статья длинная, 'много текста'. Заранее оговорюсь, что в теме буду рассматривать пример для серверного мода, но этот же принцип работает и в клиент-серверных модификациях. Разница в клиент-серверных модификациях исключительно во взаимодействии между клиентом и сервером по протоколу RPC. Предположим, что у нас имеется свой чистый сервер игры, и мы хотим добавить какое-то свое действие, например, после присоединения игрока на сервер игры. Например, некая своя запись в лог-файл сервера. Темы к ознакомлению, связанные с данным материалом: Небольшое отступление с пояснениями: Как мы знаем, базовые скрипты игры находятся у нас в 'scripts.pbo' в папке 'dta'. Эти скрипты, на минуточку, на стороне клиента игры и сервера игры идентичные, т.е. вне зависимости от того, что у нас запускается, они одинаковы и там, и там, но с одной лишь разницей, с определенного момента начинается разделение в выполнении кодов. Т.е. для сервера выполняется своя часть кода, для клиента своя. Например, для сервера выполнится код из файла missionServer.c а для клиента игры из missionGameplay.c Это я к чему - то что вы правите в скрипте для серверного мода не всегда может работать, так как эта часть кода может быть предусмотрена для клиентского мода, или наоборот. Аналогично и касается отдельных функций в коде сервера. Например, комманда GetGame().Chat("MyMessage", "colorAction"); выполняется только на клиентской стороне, а GetGame().Chat("MyMessage"); только на серверной (за исключением случаев, когда авторы игры могут ломать эти самые комманды с патчами обновлений). Но бывают и комманды, выполняющиеся и на сервере и на клиенте игры. Например, комманда Print("MyLogMessage"); выводящая в 'script.log' нужный нам текст. Вдаваться в особенности взаимодействия между сервером и клиентом игры не буду, скажу лишь то, что работает оно через id (идентификаторы вызова) и процедуру RPC (см. события OnRPC) Для ищущих и любопытных сразу отмечу, что можно делать одну общую функцию, разделяющую в зависимости от клиента и сервера код на нужное выполнение коммандами: GetGame().IsMultiplayer() - будет true(истина) если игра запущена для игры по сети, или false(ложь) во всех иных случаях GetGame().IsClient() - будет true(истина) если игра запущена клиентская часть игры (в том числе и если offline версия тоже), или false(ложь) во всех иных случаях GetGame().IsServer() - будет true(истина) если игра запущена серверная часть игры, или false(ложь) во всех иных случаях Не буду вдаваться и в подробности, но думаю эта информация вам пригодится, если вы всерьез решились заняться данной игрой. Добавлю только то, что игра может запускаться в 3 режимах: 1) Сервер 2) Клиент Мультиплеера 3) Клиент Offline версия, и во всех 3 случаях будут работа игры будет отличаться (к примеру, в Offline не будет PlayerIdentify, т.е. идентификатора игрока). Так вот, вернемся к нашему моду. Игрок с английского у нас Player. Логично предположить, что и название нужных нам событий и функций будут также содержать такой текст. Сразу отмечу, что у данной игры, как и у любой c++ подобной программы. есть подразделение по классам и подклассам. и практически все скрипты и функции игры разделены именно на них. Т.е. Если мы хотим искать Player - ищем его поиском по нахождению в папке (В Notepad++ есть крайне полезная опция, зажимаем CTRL+F и в 3 вкладке будет такой поиск). Среди результатов поиска будет много файлов и текстов. Нас интересует файл со строкой, начинающейся на class. В нашем же случае это будет 'class PlayerBase', который вы и найдете. Это базовый класс, содержащий в себе основные функции и события, связанные с персонажем, например DropItem - скидывает вещь, RemoveAllItems удаляет все вещи с игрока (см перевод текста в переводчике с англ.), а события EEKilled и OnConnect выполняются на сервере игры соответственно при смерти (и убийстве) игрока, и при присоединении к серверу. Отступление: Каждая функция имеет свой синтаксис. void - функция без возврата значения, например void OnConnect(), а бывают функции с возвратом значений, например bool IsBleeding(), возвращающая true(истина) если игрок страдает от кровотека, и false если нет. Также у каждой функции могут быть свои входящие и используемые переменные, например у void OnConnect() их нет, а у void EEKilled( Object killer ) есть. Вернемся к нашим 'интересностям' Как вы поняли уже, нас интересует OnConnect(). Открываем найденный файл PlayerBase.c. Ищем функцию OnConnect() поиском по файлу На патче 1.06 она выглядит вот так: void OnConnect() { Debug.Log("Player connected:"+this.ToString(),"Connect"); // analytics GetGame().GetAnalyticsServer().OnPlayerConnect( this ); m_PlayerOldPos = GetPosition(); if( m_AnalyticsTimer ) m_AnalyticsTimer.Run( 60, this, "UpdatePlayerMeasures", null, true ); //construction action data ResetConstructionActionData(); } Теперь, как вы сами понимаете, нам надо внести нужные нам изменения. Но как же это делать правильно, чтобы не сломать ничего в игре и модах? Объясняю ниже: Так что же нам делать то? Ведь мы не можем перепаковывать 'scripts.pbo' сервера, иначе включенный параметр verifysignatures перестанет пускать на сервер игроков. Отвечаю вам. Создайте свой текстовый файл, заполните его следующего вида данными: modded class PlayerBase extends ManBase { override void OnConnect() { super.OnConnect(); Pring("[MyTestLog] Player connected:"+this.ToString()); } } затем сохраните его в формате .с вместо txt. Как видите, вверху в файле modded class. Modded означает, что мы будем модифицировать базовый класс игры, или проще говоря писать мод на данный класс. Перед функцией OnConnect появилась override, что в переводе с англ. означает переопределение. Т.е. мы в класс PlayerBase будем переопределять функцию OnConnect. Отступление про override: Как некоторые любопытные заметили, в некоторых функциях уже имеются override. Не буду вдаваться в подробности данной структуры, скажу лишь то что в игре если главные базовые классы, есть мелкие наследуемые классы (для понимания можно подкатегориями их назвать). Так вот. один и тот же объект в игре может быть отображен в нескольких переменных под разными классами, но игровым объектом он останется одним и тем же. Делается это для того, чтобы получить доступ к тем или иным функциям. Для примера, в классе EntityAI (общий базовый класс всех объектов в игре) нет функции установки количества вещей SetQuantity (как например количество вещей), а у класса ItemBase такая функция есть. Вот для того чтобы выполнить нужное нам действие используют конверсию из одного класса в другой. хотя сам игровой объект от этого не изменяется никак. Пример такой конверсии в своих init.c миссии сервера можете наблюдать в таком вот виде: itemEnt = itemTop.GetInventory().CreateInInventory("Rag"); if ( Class.CastTo(itemBs, itemEnt ) ) itemBs.SetQuantity(4); Где сначала создается тряпка и записывается в класс EntityAI, а затем для совершения действий выполняется конверсия класса предмета в подкласс ItemBase с другими функциями, почле чего уже вызывается функция и используется параметр 4, означающий задать предмету количество 4 (Set Quantity в переводе установить количество). Также, есть у любого класса в игре, как и в c++, конструкторы и деструкторы класса. Указывать их не обязательно, но они могут иметься в классах. Пример своего класса: class My_MissionServerClassMod { void My_MissionServerClassMod() { Print("Build My_MissionServerClassMod TECT"); } void ~My_MissionServerClassMod() { Write_Log("DeBuild My_MissionServerClassMod"); } } Здесь: void My_MissionServerClassMod() - конструктор класса, выполняется в момент, когда создается объект или переменная этого класса. Т.е. в игре каждый персонаж имеет свой объект в игровом мире. Проще говоря, каждый игровой персонаж (в т.ч. и мертвый это объект класса PlayerBase). переменной такие вещи можно задавать вот так: ref My_MissionServerClassMod MyPeremennaya = new My_MissionServerClassMod; void ~My_MissionServerClassMod() - деструктор класса, выполняется в момент, когда объект или переменная удаляются с памяти, например скриптово удаление объекта с карты GetGame().ObjectDelete(MyPeremennaya); или при закрытии сервера если это переменная. Через override деструкторы и конструкторы переписывать нельзя, их в своем мод-скрипте просто объявляете, например в таком виде: modded class My_MissionServerClassMod { void My_MissionServerClassMod() { Print("Build My_MissionServerClassMod TECT"); } void ~My_MissionServerClassMod() { Write_Log("DeBuild My_MissionServerClassMod"); } } В этом случае они сами допишутся к оригинальным вызовам родного класса игры, если такие вообще были объявлены. Вернемся к объяснению в нашем классе PlayerBase: Теперь посмотрите функцию OnConnect . Как видите, куча кода в ней отсутствует, но появились 2 новые строки. Комманда super.OnConnect(); позволит нам вызвать оригинальную функцию базового класса игры с сохранением как всех ее оригинальных действий, так и зависимостей из других связанных классов в игре (напомню, в игре один и тот же объект может быть в разных классах и разных переменных). Вы сразу спросите: 'А зачем так, можно же взять оригинальный код и переписать его как нам надо' или 'А можно ли взять и переправить базовый оригинальный код?' - отвечаю - делать так тоже можно, но крайне не желательно. У вас, как мы можем догадываться, в игре могут быть разные модификации, и данный класс может с данной функцией встретиться в другом моде. Если вы вместо такого вызова вставите весь оригинальный код функции игры, вы тем самым можете сломать запуск одного из модов, которые у вас стоят. Вторая же строка в данном файле - Print("[MyTestLog] Player connected:"+this.ToString()); - т.е. запись в script.log метки с текстом [MyTestLog] Player connected:{данные о персонаже} (где + this подставит вместо текста текущие данные персонажа из данного класса, а функция-модификатор ToString() преобразует эти данные в формат текстовой строки для вывода(иначе сервер выдаст вам ошибку, так как this в данном случае - это объект текущего класса, т.е. Playerbase)). Сразу же упомяну для всех страждущих, комманда +this.ToString() не выведет данных о нашем персонаже в логе, даже не выведет никнейм или его данные. Для вывода таких сведений надо писать дополнительный код такого вида: modded class PlayerBase extends ManBase { override void OnConnect() { super.OnConnect(); PlayerIdentity identity_player = this.GetIdentity(); string nickname_player = identity_player.GetName(); string steam64id_player = identity_player.GetPlainId(); string bis_id_player = identity_player.GetId()(); Pring("[MyTestLog] Player with name " + nickname_player + "(steam64id=" + steam64id_player + " bisid=" + bis_id_player + ")connected!"); } } Собственно, этот код в готовом и сформированном вами виде вы и кладете в свой серверный мод, он у вас уже в готовом виде. Отступление на тему: В коде своего скрипта можно использовать все оригинальные функции, имеющиеся в базовом классе. который вы меняете. Также можно использовать и любые другие функции из других классов, предварительно конвертируя и используя переменные этих классов в игре. Также можно беспрепятственно использовать все переменные из модифицируемой функции и класса, ссылаясь на них, но не забывайте, что эти же переменные могут меняться и использоваться с других функциях. Куда размещать файл в своем моде, спросите вы? Отвечаю - поглядите в каком расположении находится файлик с оригинальным классом PlayerBase (4_World\Entities\ManBase\PlayerBase.c) и разместите в своем моде его по такому же пути, название файла не сильно важно, но желательно сохранять оригинальные имена для упрощения задач самим же себе. (на самом деле сервер читает скрипты в алфавитном порядке из main-разделов игры типа 5_Mission или 4_World) Любителей скриптить и писать свои моды с большим опытом работы с игрой может заинтересовать вопрос 'можно ли в моде добавлять свои переменные и функции, и вызывать их из базовых оригинальных (нативных) классов игры?' - отвечу, да, можно. Вы просто добавляете эти переменные и функции как обычные классы, например, так: modded class PlayerBase extends ManBase { string myPeremennaya = ""; override void OnConnect() { super.OnConnect(); MyFunctia(); } void MyFunctia() { Pring("[MyTestLog] Player connected:" + myPeremennaya); } } Обращу внимание, что к добавленным таким образом функциям и переменным можно обращаться лишь из своего мода, либо из других модов но только после указания зависимостей ваших других модов с текущим в cpp файле мода. Доп. информация: Отмечу сразу, что указанный в теме способ подходит для дописывания и модификации оригинальных классов скриптов сервера от разработчиков и модификации чужих модов с помощью моддинга. Изменять сам родной код функции без дописывание не рекоммендуется, но если это для вас требуется - используйте следующее: Изменение оригинальных скриптов, для которых не предусмотрена операция 'modded class' в движке игры, а также классов и функций, которые защищены языком и движком игры от такого рода действий через серверные моды не получится. Если вы столкнулись с этим, вам проще распаковать scripts.pbo и поместить папку scripts в корень сервера игры, добавить в параметры запуска сервера параметр -FilePatching и изменять напрямую в папке необходимые вам файлы. Также, подобные описанные выше оранжевым цветом действия будут работать, если вы будете использовать override без использования строки-комманды super в своей функции. Важно: не выполняйте указанную выше доп. информацию на стороне клиента игры, иначе это может стать причиной неработоспособности вашего клиента игры и входа на сервера, поскольку сервера игры поумолчанию защищены от такого рода действий и будут исключать вас с сервера на попытках входа на него! И так, если вы смогли осилить данную тему с кучей текста, вдумчиво и с пониманием всего описанного, вы сможете создать любой свой мод без особых проблем. Если же данная тема при изучении вызывает особые трудности, советую вам заказать готовое решение у кого-либо в специальной ветке форума. P.S. Прошу извинить меня за излишнюю монотонность чтения и оформления темы, а также неточности, я далеко не эксперт ?
  3. 1 балл
    123new

    Сигарета

    сигарет мод на 1.03 у фидова был вроде
  4. 1 балл
    в таком случае прекращаем флуд не по теме подраздела, поглядите раздел где пишете
  5. 1 балл
    Irkutsk86

    Анти абуз перезаходов на сервер

    @ToRRan4Y что то похожее уже есть в мастерской https://steamcommunity.com/sharedfiles/filedetails/?id=2290101680
  6. 1 балл
    123new

    Вайп и Как с ним бороться?!

    Одноименные bin файлы и их копии в storage попробуй удалять. например изменил types - удали одноименные bin и стартуй сервер. А вообще оно само применяться должно с течением пары рестартов и для нового лута (для имеющегося на сервере старые правила остались, т.к. лут создался)
  7. 0 баллов
    Runner

    Урон по постройкам

    Как увеличить или уменьшить урон по постройкам с оружия и гранат?
×
×
  • Создать...

Важная информация

Используя этот сайт, вы автоматически обязуетесь соблюдать наши Правила и Политика конфиденциальности.
Чтобы сделать этот веб-сайт лучше, мы разместили cookies на вашем устройстве. Вы можете изменить свои настройки cookies, в противном случае мы будем считать, что вы согласны с этим.

Поддержка