Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Нужна помощь?

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

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

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок
  • Загляните на торговую площадку

    Там вы можете купить
    Всё что касается игровых серверов
  • 0
BorizzK

Такой вот вопос. Удаление обьектов с карты при выключении сервера.

Вобщем в процессе работы сервера происходят рандомные динамические события и вместе с ними на карте спавнятся некоторые обьекты

Если время их жизни истекает и настает время нового события и в радиусе видимости нет игроков обьекты удаляются с карты

Но

Если выключение корректно (запланированный рестарт например), вызов функции удаления происходит из деструктора класса

Все отрабатывает

Ошибок нет

Но после рестарта некоторые обьекты на месте

Тогда я замутил функцию-задержку с проверкой

 

	float TimeWait(Object object, float timeW)
	{
		float cTick = GetGame().GetTickTime() + timeW;
		while(object || GetGame().GetTickTime() < cTick )
		{
			if ( GetGame().GetTickTime() >= cTick ) break;
		}
		return GetGame().GetTickTime();
	}

и вызываю ее

 

if (object)	tW = TimeWait(object, timeW);

задержка реально происходит - делал ее 60 секунда да же

НО! обьекты эти после рестарта опять на месте

 

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

к тому же это полезно в случае крашей

 

и все же

почему обьекты не удаляются при завершении работы сервера?

 

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites

23 answers to this question

Recommended Posts

  • 0
2 часа назад, BorizzK сказал:

почему обьекты не удаляются при завершении работы сервера?

Возможно удаление происходит уже после того, как сработало отключение связи с БД...

 

В деструктор добавь проверку Hive - есть ли он.

 

P.S. А вообще в деструкторе удалять объект...... ну это такое... Ведь деструктор и должен сработать при удалении\уничтожении))))) что же он будет удалять, если ты прямо из деструктора вызываешь еще раз удаление объекта) который и попал в деструктор потому что произошло уничтожение)

Хер его знает, что там могло произойти)

 

Добавляй свои объекты в список, какого либо класса - менеджера.

И вот в этом менеджере, внутри деструктора, просто пробегись по списку и грохни все объекты.

...Да и то не совсем корректно - объект может быть удален игрой(не из БД) до отработки деструктора твоего класса - менеджера. Так что, - либо убедись, что он будет первым удаляться. А еще лучше, - за минуту до рестарта пробегайся по списку и удаляй. Ну и костыль про который ты пишешь, в общем то и не костыль, а вполне себе нормальный подход.

Edited by NoNameUltima (see edit history)

Share this post


Link to post
Share on other sites



  • 0

NoNameUltima Не - я про деструктор класса в котором все работает

При создании 1 раз - при старте сервера отрабатывает конструктор

При выключении сервера и уничтожении класса деструктор

Этож аксиома и ты сам об этом знаешь


 

Цитата

 

Добавляй свои объекты в список, какого либо класса - менеджера.

И вот в этом менеджере, внутри деструктора, просто пробегись по списку и грохни все объекты.

 

 

Я это и делаю

некоторые удаляются а некоторые нет - рандомно

 

За минуту до рестарта

Как я это определю? А если рестарт мышкой или незапланированно через баттлу админом

 

 

Share this post


Link to post
Share on other sites
  • 0

Тебе проще не связывать с рестартом, а сделать скрипт в 2 частях:
1) сам непосредственный спавн нужного при старте севрака
2) сохранение в процессе работы сервера этих объектов, например, в папке или xml-файле с записью координат и id нужного объекта
и непосредственно перед вызовом спавна тупо удалять все старые объекты с карты по известным и записанным тебе координатам.

Edited by 123new (see edit history)

Share this post


Link to post
Share on other sites
  • 0

123new перед вызовом спавна они и так удаляются - тк они в переменных класса - в массиве

они не удаляются в деструкторе при корректном выключении сервера когда класс деструктится

точнее - то удаляются то нет - либо удаляются но не все

сохраняю я их в профиле

 

у меня вот вопрос - тк проверить все руки не доходят

 

скажем создал я object

он в мире персистетно - те не как билдинг который не сохранится в базе - и имеет свой object id как и все скажем LargeTent<0b44c4aa>

он сохранится в базе и не удалится в деструкторе класса где он был создан при рестарте

при следующем старте у него будет такой же object id или нет?

 

Share this post


Link to post
Share on other sites
  • 0
2 часа назад, BorizzK сказал:

При выключении сервера и уничтожении класса деструктор

Этож аксиома и ты сам об этом знаешь

Харе бредить.

При чем тут то что ты написал?

У тебя есть созданный объект.

При выключении сервера произошло его уничтожение(выделенная память была освобождена и т.д.) был вызван ДЕСТРУКТОР объекта - код который должен отработать при уничтожении объекта. И ты ПРЯМО В ДЕСТРУКТОРЕ вызываешь удаление того же объекта!!!!

15 часов назад, BorizzK сказал:

вызов функции удаления

 

ОН ЕПТЬ УЖЕ В ДЕСТРУКТОРЕ находится! А ты в деструкторе пишешь DeleteObject - и что ему делать? Функция DeleteObject, ОБЯЗАННА вызвать деструктор объекта, она вызывает, и ОПЯТЬ  и ОПЯТЬ и ОПЯТЬ, потому что каждый раз когда она его вызывает, там прописано тобой - DeleteObject

Как можно в деструкторе вызвать удаление объекта если объект попадает в деструктор только при удалении?

Ты какой то парадокс изобрел - петля времени прям.

Share this post


Link to post
Share on other sites
  • 0

NoNameUltima 

Я ПРО ВЫЗОВ УДАЛЕНИЯ ОБЬЕКТА В ДЕСТРУКТОРЕ КЛАССА ПИСАЛ
цитата: вызов функции удаления происходит из деструктора класса

Class MyClass
{
	
	Object object = NULL;
 
	void MyClass()
	{
		ClassInit();
	}

	void ~MyClass()
	{
		ObjectsClear();
	}

	void ClassInit()
	{
		object = GetGame().CreateObject("TestObject", "1000 10 1000");
	}

	void ObjectsClear()
	{
		object.Delete();
	}

}

При запуске сервера и инициализации класса или в процессе - там еще функции есть по таймеру - создаются обьекты на карте
В деструктора при выключении сервака вызов функции очистки

 

А ты думал я про какой деструктор?

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites
  • 0

BorizzK хОтя мля. ну ты и велосипедист...

 

Этж псц....

 

чтобы создать тебе объект, надо сделать

 

GetGame().CreateObject("MyClass",........

Которая нативно создаст еще один объект внутри себя.

Этож псдц велосипед....... с тремя педалями.

 

я даже боюсь представить весь код)

Edited by NoNameUltima (see edit history)

Share this post


Link to post
Share on other sites
  • 0

NoNameUltima 

Вот ты мне и обьясни свой ход мысли

 

Обьект класса будет существовать до тех пор пока не будет вызвано выключение сервера (корректное) (в итоге будет вызван деструктор) или не будет удален обьект класса

деструкторы классов вызываются в обратной последовательности относительно последовательно инициализации при включении

Те если мой класс инициализировался первым то при выключении он деструктнется последним

 

А следовательно пока запущен сервер клас будет существовать и будут существовать все его переменные и ссылки на созданные обьекты в них

Серверу покер в каком классе создан обьект

 

В логгировании все прекрасно видно

 

 

 

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites
  • 0

BorizzK

По хорошему, тебе нужен простой класс, с объектом, в котором внутри деструктора прописать удаление из БД, но доступа к хайв дайз пока не предоставляет(и будет ли - хз)...

А функция DeleteObject удалит и из БД, но вот незадача, - только пока сервер работает.

А при выключении сервера, сработает уже в движке корректное завершение работы - будет освобождена память, но объекты остануться в БД.

так что решается это только 2 путями -

1. Создай скрипт который будет учитывать время ДО рестарта сервера, и за минуту до рестарта удалять корректно все объекты.

2. Так как ты и сделал сейчас - при респавне объекта проверять - нет ли такого же рядом.

 

ЗЫ - Первый скрипт для сервера все равно крайне желателен, - чтобы какой то ряд действий произвести - кик всех игроков к примеру и т.п. т.к. некоторые процессы возможно реализованны в ОнДисконнект.(операции с валютой и т.п.)

 

 

Share this post


Link to post
Share on other sites
  • 0
4 минуты назад, BorizzK сказал:

Вот ты мне и обьясни свой ход мысли

Я тебе уже написал, что при выключении сервера, работа ХАЙВа (БД) может быть завершена ранее, чем твой скрипт в деструктор попадает, т.к. движку уже до 3.14зды, - деструкторы то отработают, но не гарантированно что удалят с базы.

Share this post


Link to post
Share on other sites
  • 0

NoNameUltima Ну я таким путем и собрался идти

Те выходит при вызове заершения работы процесса он освобождает быза и дальнейшие действия уже происходят с памятью

Вот поэтому игроков и тп откатывает на момент ДО вызова завершения работы...

 

Понятно что при краше ни о каких деструкторах и тп речи быть не может потому оставлю как есть

 

Share this post


Link to post
Share on other sites
  • 0

NoNameUltima Я догадывался... дебилизм. Мне казалось логичным что двиг отключает и сохраняет базу после завершения всех функций и процедур...

 

Вобщем вопрос исчерпан

Share this post


Link to post
Share on other sites
  • 0

BorizzK И кстати, в init.c есть инициализация хайв.

Создай переменную глобальную под него(только обязательно в папке 3_Game ) -

 

Hive GLOBAL_HIVE;

 

а в init.c вот этот код, в main

Hive ce = CreateHive();
    if ( ce )
        ce.InitOffline();

 

замен на

GLOBAL_HIVE = CreateHive();

if ( GLOBAL_HIVE )

{ GLOBAL_HIVE.InitOffline(); }

 

и вот после этого, в деструкторе объекта попробуй вписать

if ( GLOBAL_HIVE )

{ Print("Есть соединение с БД"); }

else

{ Print("Нет соединения с БД"); }

 

ну по крайней мере, посмотреть так ли это...

 

Edited by NoNameUltima (see edit history)

Share this post


Link to post
Share on other sites
  • 0
1 час назад, BorizzK сказал:

123new перед вызовом спавна они и так удаляются - тк они в переменных класса - в массиве

они не удаляются в деструкторе при корректном выключении сервера когда класс деструктится

точнее - то удаляются то нет - либо удаляются но не все

сохраняю я их в профиле

 

у меня вот вопрос - тк проверить все руки не доходят

 

скажем создал я object

он в мире персистетно - те не как билдинг который не сохранится в базе - и имеет свой object id как и все скажем LargeTent<0b44c4aa>

он сохранится в базе и не удалится в деструкторе класса где он был создан при рестарте

при следующем старте у него будет такой же object id или нет?

 

а на кой хрен их удалять при выключении сервера или деструктора? Я может чего-то не понимаю, но как по мне, зная реальные координаты этих объектов на карте, удалить их труда не составит перед спавном новых. Так зачем делать велосипед?

Share this post


Link to post
Share on other sites
  • 0

123new они рандомно по карте спавнятся

место текущего спавна и так проверяется перед спавном по всем основным кретериям

но - если серв рестартнуть спан же может быть и в другом месте

потому я сохраняю при спавне в профиль сервера инфу о координатах и класснеймах что были заспавлены и при старте сервера в коонструкторе беру их оттуда и там подчищаю

 

просто хотел сделать совсем красиво

но не вышло

 

Share this post


Link to post
Share on other sites
  • 0

BorizzK я не про место текущего спавна говорю, а про место, которое выбрано скриптом для появления объекта. Проще говоря, вещь спавнится и сразу же записывается координата где именно. Скриптом ничего сложного нет такое сделать. Ровно как и очистку и прочее

Share this post


Link to post
Share on other sites
  • 0

123new да оно так и есть

в этом отношении все нормально

просто стало интересно почему при вырубании сервера и вызове функции очистки из деструктора класса объекты не удаляются из базы

а она оказывается отключается раньше

 

Share this post


Link to post
Share on other sites
  • 0

123new база отключается то до выполнения крайнего детруктора, то во время и либо не удаляются вообще все обьекты, либо удаляется только часть

есть идея одна - сеня проверю отпишусь

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By 123new
      И так, ребятки, вот вам небольшая 'полезняшка' от меня, и совершенно бесплатно!
       
      Описание:

      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      или создать их самим со следующим содержанием:
      Script.c
      /* Описание: Скрипт выдачи индивидуального стартового лута, скина игрока и точек спавна Автор: 123new Установка: 1. По пути: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\ создать папку 'CustomSpawnPlayerConfig' и поместить в нее 3 файла скрипта: Script.c Sets.c init_mod.c 2. В файле: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c в самом верху файла добавить: #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c" 3. В папке, обозначенной параметром запуска сервера '-profile=', поместить файл с именем CustomSpawnPlayerConfig.txt и заполнить его данными по следующему формату: UID|Skin_player|sets_numbers|points_spawns где UID - это steam64id от профиля игрока в steam Skin_player - точный id скина игрока (можно указать 0 для отключения опции) sets_numbers - номер сета со стартовым лутом (можно указать несколько через ';', указать один всего, либо указать 0 для отключения опции) points_spawns - координаты спавна игрока на карте в формате 'x y z' (можно указать несколько через ';', указать всего одну точку, либо указать 0 для отключения опции) Пример: 76561198141889254|SurvivorM_Oliver|1|12955.091797 16.115206 7993.588379 76561198141889256|SurvivorM_Oliver|1;2|14791.965820 76.481781 14041.661133;12029.079102 196.356125 7274.689941 76561198141889253|SurvivorM_Oliver|0|0 4. В файле Sets.c в папке: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\ настроить стартовый лут для ваших игроков и написать собственные сеты ВАЖНО: количество сетов можно делать любое, номера сетов брать от 1 и выше (не должно быть -1, либо 0, только от 1 и выше) Все что укажете в блоке default будет применено для всех игроков при респавне в случае, если им не выдан никакой сет! P.S. Прикрепить к соспавненному оружию магазин не получится, рабочего кода я не смог найти!! Если у вас папка активной миссии сервера отличается от dayzOffline.chernarusplus то переименуйте ее в строке, вписываемой в: {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c */ class CustomSpawnPlayerConfig { private string Location_Directory_config = "$profile:"; // Расположение папки с конфигом скрипта private string Location_filename_config = "CustomSpawnPlayerConfig.txt"; // имя файла с конфигом скрипта private string default_log_block_name = "[CustomSpawnPlayerConfig] "; // Стандартный блок скрипта для идентификации с script.log private string disable_read_parameter = "0"; // Стандартное значение (без кавычек) для обозначения в файле конфига скрипта неиспользование параметра private string block_split_parameters_config = "|"; // Символ, обозначающий разделение параметров при чтении файла конфига private string block_split_multi_parameters_config = ";"; // Символ, обозначающий перечисление в одной ячейке параметра нескольких параметров при чтении файла конфига private bool enabled_loading_custom_spawnpoints = true; // Параметр, включающий и отключающий возможность использования приватной точки спавна для каждого игрока. В случае отключения кастомная точка спавна будет отключена для всех поумолчанию, вне зависимости от данных в конфиге! private bool enabled_loading_custom_sets = true; // Параметр, включающий и отключающий возможность использования приватного сета для каждого игроков. В случае отключения выдача сетов будет отключена для всех поумолчанию, вне зависимости от данных в конфиге, будет выдаваться только сет для всех игроков! private bool enabled_loading_custom_skins = true; // Параметр, включающий и отключающий возможность использования индивидуального стартового скина игрока для каждого игрока. В случае отключения эта возможность будет отключена для всех поумолчанию, вне зависимости от данных в конфиге! // ------------------------------------------------------------ // ---------------- NEXT CODE DON'T EDIT ----------------- // ------------------------------------------------------------ ref map<string, ref array<vector>> players_spawnpoints = new map<string, ref array<vector> >; ref map<string, ref array<int>> players_sets = new map<string, ref array<int> >; ref map<string, string> players_skins = new map<string, string>; private bool enabled_loaded_successfull_config = false; string Log_CustomSpawnPlayerConfig_GetDateTime() { private int year, month, day, hour, minute, second; GetYearMonthDay(year, month, day); GetHourMinuteSecond(hour, minute, second); string returned_message = "[" + day.ToStringLen(2) + "." + month.ToStringLen(2) + "." + year.ToStringLen(2) + " - " + hour.ToStringLen(2) + "." + minute.ToStringLen(2) + "." + second.ToStringLen(2) + "] "; return returned_message; } bool Check_coords_disable(vector coord) { private bool ret_zn = false; private float pos_x = coord[0]; private float pos_y = coord[1]; private float pos_z = coord[2]; if ((pos_x == 0.0) & (pos_y == 0.0) & (pos_z == 0.0)) { ret_zn = true; } return ret_zn; } vector Set_Read_coords_disable() { return Vector(0.0, 0.0, 0.0); } void CustomSpawnPlayerConfig() { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + "CustomSpawnPlayerConfig initialize start!"); Read_Update_Config(); } void ~CustomSpawnPlayerConfig() { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + "CustomSpawnPlayerConfig work end, class closed!"); } void Read_Update_Config() { private string name_block_work = "[ReadAndUpdateSettings] "; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + " Started Reading config!"); private array<string> readed_lines_config = ReadFileConfig(); private bool check_normal_read = AnaliseFileConfig(readed_lines_config); if (check_normal_read) { LoadFileConfig(readed_lines_config); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "config readed successfull!"); enabled_loaded_successfull_config = true; } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "config read failed, work script disabled for players!"); enabled_loaded_successfull_config = false; } } array<string> ReadFileConfig() { private string name_block_work = "[ReadFileConfig] "; private array<string> readed_lines_config = new array<string>; readed_lines_config.Clear(); if (FileExist ( (Location_Directory_config + Location_filename_config) ) ) { private string line_content; FileHandle file = OpenFile((Location_Directory_config + Location_filename_config), FileMode.READ); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Open file config: " + (Location_Directory_config + Location_filename_config)); if (file != 0) { while ( FGets( file, line_content ) > 0 ) { readed_lines_config.Insert( line_content); } CloseFile(file); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! CAN'T OPEN FILE CONFIG : " + (Location_Directory_config + Location_filename_config)); } //readed_lines_config.Debug(); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! CAN'T FOUND FILE CONFIG OR DIRECTORY: " + (Location_Directory_config + Location_filename_config)); } return readed_lines_config; } bool AnaliseFileConfig(array<string> readed_lines_config) { private bool return_zn = true; private string name_block_work = "[AnaliseFileConfig] "; if (readed_lines_config.Count() > 0) { foreach (string line : readed_lines_config) { if (line.Contains(block_split_parameters_config)) { private array<string> splited_line = new array<string>; line.Split( block_split_parameters_config, splited_line ); if (splited_line.Count() == 4) { private string UID_player = splited_line.Get(0); private string default_skin_player = splited_line.Get(1); private string sets_numbers_player = splited_line.Get(2); private string points_spawn_player = splited_line.Get(3); if ((UID_player == "") || (default_skin_player == "") || (sets_numbers_player == "") || (points_spawn_player == "")) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Lines in Readed file is not correct, please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Readed file is have incorrect count parameters with a tag '" + block_split_parameters_config + "', please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Readed file can't have a tag '" + block_split_parameters_config + "', please, fix your config script!"); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Line checking: " + line); return_zn = false; break; } } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "ERROR!!! Config file is empty, fix your config script!"); return_zn = false; } return return_zn; } void LoadFileConfig(array<string> readed_lines_config) { private string name_block_work = "[LoadFileConfig] "; players_spawnpoints.Clear(); players_sets.Clear(); players_skins.Clear(); foreach (string line : readed_lines_config) { private array<string> splited_line = new array<string>; splited_line.Clear(); line.Split( block_split_parameters_config, splited_line ); private string UID_player = splited_line.Get(0); private string default_skin_player = splited_line.Get(1); private string sets_numbers_player = splited_line.Get(2); private string points_spawn_player = splited_line.Get(3); private array<vector> temp_players_spawnpoints = new array<vector>; temp_players_spawnpoints.Clear(); array<int> temp_players_sets = new array<int>; temp_players_sets.Clear(); array<string> temp_players_spawnpoints_string = new array<string>; temp_players_spawnpoints_string.Clear(); array<string> temp_players_sets_string = new array<string>; temp_players_sets_string.Clear(); if (points_spawn_player.Contains(block_split_multi_parameters_config)) { points_spawn_player.Split( block_split_multi_parameters_config, temp_players_spawnpoints_string ); } else { temp_players_spawnpoints_string.Insert(points_spawn_player); } foreach (string line_spawnpoint : temp_players_spawnpoints_string) { if (line_spawnpoint == disable_read_parameter) { temp_players_spawnpoints.Insert(Set_Read_coords_disable()); } else { temp_players_spawnpoints.Insert(line_spawnpoint.ToVector()); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Generated massive for " + UID_player + " with " + temp_players_spawnpoints.Count().ToString() + " spawnpoints."); if (sets_numbers_player.Contains(block_split_multi_parameters_config)) { sets_numbers_player.Split( block_split_multi_parameters_config, temp_players_sets_string ); } else { temp_players_sets_string.Insert(sets_numbers_player); } foreach (string line_set : temp_players_sets_string) { if (line_set == disable_read_parameter) { temp_players_sets.Insert(0); } else { temp_players_sets.Insert(line_set.ToInt()); } } if (default_skin_player == disable_read_parameter) { default_skin_player = "0"; } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Generated massive for " + UID_player + " with " + temp_players_sets.Count().ToString() + " sets."); Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Detected for " + UID_player + " skin " + default_skin_player); players_spawnpoints.Insert(UID_player,temp_players_spawnpoints); players_sets.Insert(UID_player,temp_players_sets); players_skins.Insert(UID_player,default_skin_player); } } vector Load_And_Check_Spawnpoints(PlayerIdentity identity, vector pos_default) { private string name_block_work = "[Load_And_Check_Spawnpoints] "; private vector retun_pos = pos_default; if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_spawnpoints) { if ((players_spawnpoints.Count() > 0) && (enabled_loaded_successfull_config)) { if (players_spawnpoints.Contains(UID_P)) { private array<vector> readed_lines_config = new array<vector>; readed_lines_config = players_spawnpoints.Get(UID_P); private vector retun_pos_check = readed_lines_config.GetRandomElement(); if (Check_coords_disable(retun_pos_check)) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private spawn point. Will be used default spawn point!"); } else { retun_pos = retun_pos_check; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private spawn point: " + retun_pos.ToString()); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private spawnpoint for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private spawnpoints is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal spawnpoints from config file script!"); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn point: " + retun_pos.ToString()); return retun_pos; } string Load_And_Check_SpawnSkin_Player(PlayerIdentity identity, string characterName) { private string name_block_work = "[SelectStartSkinPlayer] "; private string retun_skin = characterName; if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_skins) { if (players_skins.Count() > 0) { if (players_skins.Contains(UID_P)) { private string readed_skin = players_skins.Get(UID_P); if (readed_skin == "0") { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private skin setting, will be used default setting game!"); } else { retun_skin = readed_skin; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private skin setting: " + retun_skin); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private skin setting for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private skin setting is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal skin player settings from config file script!"); } } Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used skin: " + retun_skin); return retun_skin; } void Load_And_Check_StartLoadout(PlayerBase player) { private string name_block_work = "[SelectStartSetPlayer] "; private int use_set_id = -1; private PlayerIdentity identity = player.GetIdentity(); if(identity) { private string Name_P = identity.GetName(); private string UID_P = identity.GetPlainId(); private string Game_UID_P = identity.GetId(); private string Game_ID_P = identity.GetPlayerId().ToString(); if (enabled_loading_custom_sets) { if ((players_sets.Count() > 0) && (enabled_loaded_successfull_config)) { if (players_sets.Contains(UID_P)) { private array<int> readed_lines_config = new array<int>; readed_lines_config.Clear(); readed_lines_config = players_sets.Get(UID_P); private int chek_use_set_id = readed_lines_config.GetRandomElement(); if (chek_use_set_id == 0) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") disabled loading private set numbers. Will be used default set player! "); } else { use_set_id = chek_use_set_id; Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") setuped private set number is: " + use_set_id.ToString()); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Can't founded private sets for player " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "Config script is incorrect, checking private sets is disabled! Player: " + Name_P + "(steam64id=" + UID_P + ")"); } } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "disabled loading personal loadout sets player settings from config file script! Will be used default loadout!"); } if (use_set_id >= 0) { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn set with number is: " + use_set_id.ToString()); } else { Print(Log_CustomSpawnPlayerConfig_GetDateTime() + default_log_block_name + name_block_work + "For player " + Name_P + "(steam64id=" + UID_P + ") will be used spawn default start set without number. "); } StartSetsPlayers.StartSetsPlayer(player, use_set_id); } } private array<EntityAI> GetItemListinobject(PlayerBase player,EntityAI item, bool check_player) { array<EntityAI> EntityAI_list_items = new array<EntityAI>; EntityAI_list_items.Clear(); int attIdx = 0; int attCount = 0; EntityAI item_in_object; if ((player) && (check_player)) { attCount = player.GetInventory().AttachmentCount(); for (attIdx = 0; attIdx < attCount; attIdx++) { item_in_object = player.GetInventory().GetAttachmentFromIndex(attIdx); if ( item_in_object.IsItemBase() ) { EntityAI_list_items.Insert(item_in_object); } } } if ((item) && !check_player) { attCount = item.GetInventory().AttachmentCount(); for (attIdx = 0; attIdx < attCount; attIdx++) { item_in_object = item.GetInventory().GetAttachmentFromIndex(attIdx); if ( item_in_object.IsItemBase() ) { EntityAI_list_items.Insert(item_in_object); } } } return EntityAI_list_items; } void RemoveAllItems (PlayerBase player) { private array<EntityAI> ItemListPlayer = new array<EntityAI>; private array<EntityAI> ItemsForDelete = new array<EntityAI>; private EntityAI itemInHands_player = player.GetHumanInventory().GetEntityInHands(); if (itemInHands_player != NULL) { if (player.CanDropEntity(itemInHands_player) && player.GetHumanInventory().CanRemoveEntityInHands()) { // Print("ItemForDelete: " + itemInHands_player.ToString()); ItemsForDelete.Insert(itemInHands_player); } } ItemListPlayer = GetItemListinobject(player,NULL,true); if (ItemListPlayer.Count() > 0) { foreach(EntityAI ItemPlayer: ItemListPlayer) { private array<EntityAI> ItemInItemInInventory = GetItemListinobject(NULL,ItemPlayer,false); private CargoBase cargo = ItemPlayer.GetInventory().GetCargo(); if(cargo) { if (cargo.GetItemCount() > 0) { for (int f = 0; f < cargo.GetItemCount(); f++) { if(cargo.GetItem(f)) { ItemsForDelete.Insert(cargo.GetItem(f)); } } } } if (ItemInItemInInventory.Count() > 0) { foreach(EntityAI items_temp: ItemInItemInInventory) { if(items_temp) { ItemsForDelete.Insert(items_temp); } } } if(ItemPlayer) { ItemsForDelete.Insert(ItemPlayer); } } } if (ItemsForDelete.Count() > 0) { foreach(EntityAI item_temp: ItemsForDelete) { if(item_temp) { GetGame().ObjectDelete(item_temp); } } } } }; Sets.c
      class StartSetsPlayersConfig { void StartSetsPlayer(PlayerBase player,int use_set_id) { EntityAI itemCreated = NULL; EntityAI itemCreated1 = NULL; ItemBase itemCasted = NULL; switch( use_set_id ) //Раздаем лут (можно использовать значения от 1 и выше, только не 0 и не -1) { case 1: //Set with number 1 (Сет с номером 1) { My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку itemCreated = player.GetInventory().CreateInInventory("CoyoteBag_Green"); // Выдаем рюкзак и записываем в переменную itemCreated if (itemCreated) // Проверяем, создался ли рюкзак. Если он создался, переменная itemCreated будет не пуста и проверка пройдет { SetRandomHealthItem(itemCreated); // Выдаем рюкзаку рандомное качество itemCreated1 = itemCreated.GetInventory().CreateInInventory("Apple"); // Добавляем в инвентарь созданного рюкзака яблоко и записываем в переменную itemCreated1 if (itemCreated1) // Проверяем, создалось ли яблоко в рюкзаке, яблоко у нас с переменной itemCreated1 { SetRandomHealthItem(itemCreated1); // Выдаем яблоку рандомное качество } itemCreated1 = NULL; // Обнуляем значение переменной после работы с ней, чтобы следующая проверка прошла корректно itemCreated1 = itemCreated.GetInventory().CreateInInventory("Rag"); // Выдаем игроку бинты в рюкзак и записываем в переменную itemCreated1 if (itemCreated1) // Проверяем, создались ли бинты в рюкзаке, они у нас с переменной itemCreated1 { itemCasted = ItemBase.Cast(itemCreated1); // Выполняем преобразование в другой класс для работы с нужной нам функцией, поскольку в классе EntityAI нет нужной нам функции SetQuantity, а в подклассе ItemBase она есть. Предмет при этом так и остается один и тот же! itemCasted.SetQuantity(4); // Определяем количество для созданных бинтов как 4 штуки SetRandomHealthItem(itemCreated); // Выдаем бинтам рандомное качество, функция работает с классом EntityAI (см. в конфе файла) } } // переменную itemCreated не обнуляем далее, поскольку мы ее не используем в проверке ниже. itemCreated = player.GetInventory().CreateInInventory("TTSKOPants"); // Выдаем игроку штаны itemCreated = player.GetInventory().CreateInInventory("TTsKOJacket_Camo"); // Выдаем игроку куртку itemCreated = player.GetInventory().CreateInInventory("CombatBoots_Black"); // Выдаем игроку обувь //itemCasted = ItemBase.Cast(itemCreated); // Строка не нужна, закоментирована. используется для изменения класса EntityAI в ItemBase (чтобы нужные операции были доступны) itemCreated = player.GetInventory().CreateInInventory("CombatKnife"); // Выдаем игроку ножик в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("FNX45"); // Выдаем игроку FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); // Выдаем игроку магазины к FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); // Выдаем игроку магазины к FNX в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); // Выдаем игроку магазины к AKM в любой свободный слот в инвентаре itemCreated = player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); // Выдаем игроку магазины к AKM в любой свободный слот в инвентаре itemCreated = NULL; // Обнуляем значение переменной после работы с ней, нужно если мы будем использовать ее далее itemCreated = player.GetHumanInventory().CreateInHands("akm"); // Выдаем игроку AKM в руки if (itemCreated) // Проверяем, создался ли АКМ { itemCreated.GetInventory().CreateAttachment( "PSO11Optic" ); // Выдаем игроку на AKM оптику ПСО 11 и крепим itemCreated.GetInventory().CreateAttachment( "AK_WoodBttstck" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим itemCreated.GetInventory().CreateAttachment( "AK_WoodHndgrd" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим itemCreated.GetInventory().CreateAttachment( "AK_Suppressor" ); // Выдаем игроку на AKM цевье, приклад и глушитель, и крепим } break; } case 2: //Set with number 2 (Сет с номером 2) { break; } case 3: //Set with number 3 (Сет с номером 3) { break; } case 4: //Set with number 4 (Сет с номером 4) { break; } case 5: //Set with number 5 (Сет с номером 5) { break; } case 6: //Set with number 6 (Сет с номером 6) { break; } default: //Default starting spawn set (Сет поумолчанию для всех игроков, если хотите назначить - добавляйте здесь!) { //My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку DefaultSets(player); // Для выдачи своих сетов по рандому всем игрокам, не прописанным в скрипте, раскомментировать эту строку break; } } } void SetRandomHealthItem(EntityAI itemCreated) // Функция генерирует и применяет для предмета рандомное значение здоровья! { if ( itemCreated ) { private int rndHlt = Math.RandomInt(55,6); itemCreated.SetHealth("","",rndHlt); } } void DefaultSets(PlayerBase player) // Функция выдает сеты игрокам, не прописанным в конфигурации скрипта!!! { EntityAI itemCreated = NULL; EntityAI itemCreated1 = NULL; ItemBase itemCasted = NULL; // ниже пример, если вам нужно задать свои точки спавна для всех игроков. Этот код можно также использовать и для каждого сета индивидуально! // Код закомментирован, если это надо - раскомментируйте! // начало кода точек спавна игрока /* private array <vector> spawnpoints = {"7500 0 7500", "7500 0 7500","7500 0 7500", "7500 0 7500"}; private vector selected_spawnpoint = spawnpoints.GetRandomElement(); player.SetPosition(selected_spawnpoint); */ // конец кода точек спавна игрока private int random_set_number = Math.RandomIntInclusive(1,6); // генерируем рандом номер сета от 1 до 6 включительно (по значениям блоков case ниже) switch( random_set_number ) //Раздаем лут (можно использовать значения от 1 и выше, только не 0 и не -1) { case 1: //Set with number 1 (Сет с номером 1) { break; } case 2: //Set with number 2 (Сет с номером 2) { break; } case 3: //Set with number 3 (Сет с номером 3) { break; } case 4: //Set with number 4 (Сет с номером 4) { break; } case 5: //Set with number 5 (Сет с номером 5) { break; } case 6: //Set with number 6 (Сет с номером 6) { break; } default: //Default starting spawn set (Сет поумолчанию для всех игроков, в случае если ни один из сетов выше не выпал. { //My_Custom_Spawn_Parameters.RemoveAllItems(player); // Чтобы удалить с персонажа уже имеющиеся стандартные стартовые шмотки раскомментировать строку break; } } } } init_mod.c
      #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\Script.c" #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\Sets.c" ref CustomSpawnPlayerConfig My_Custom_Spawn_Parameters = new CustomSpawnPlayerConfig(); ref StartSetsPlayersConfig StartSetsPlayers = new StartSetsPlayersConfig(); modded class CustomMission { override void OnInit () { super.OnInit(); GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(My_Custom_Spawn_Parameters.Read_Update_Config, 120000, true); // Обновление настроек скрипта кастомных спавнов, 1 минута = 60000 } override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) { pos = My_Custom_Spawn_Parameters.Load_And_Check_Spawnpoints(identity, pos); characterName = My_Custom_Spawn_Parameters.Load_And_Check_SpawnSkin_Player(identity, characterName); super.CreateCharacter(identity, pos, ctx, characterName); return m_player; } override void StartingEquipSetup(PlayerBase player, bool clothesChosen) { super.StartingEquipSetup(player, clothesChosen); My_Custom_Spawn_Parameters.Load_And_Check_StartLoadout(player); } }  

       
      2. В файле:
      {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c в самом верху файла добавить:
      #include "$CurrentDir:mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c" Чтобы получилось примерно так

       
      3. В папке, обозначенной параметром запуска сервера '-profile=', поместить файл с именем CustomSpawnPlayerConfig.txt
      и заполнить его данными по следующему формату:
      UID|Skin_player|sets_numbers|points_spawns где UID - это steam64id от профиля игрока в steam
      Skin_player - точный id скина игрока (можно указать 0 для отключения опции)
      sets_numbers - номер сета со стартовым лутом (можно указать несколько через ';', указать один всего, либо указать 0 для отключения опции)
      points_spawns - координаты спавна игрока на карте в формате 'x y z' (можно указать несколько через ';', указать всего одну точку, либо указать 0 для отключения опции)
      Пример:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      76561198141889254|SurvivorM_Oliver|1|12955.091797 16.115206 7993.588379 76561198141889256|SurvivorM_Oliver|1;2|14791.965820 76.481781 14041.661133;12029.079102 196.356125 7274.689941 76561198141889253|SurvivorM_Oliver|0|0  
      4. В файле Sets.c в папке:
      {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\ настроить стартовый лут для ваших игроков и написать собственные сеты
      ВАЖНО: количество сетов можно делать любое, номера сетов брать от 1 и выше (не должно быть -1, либо 0, только от 1 и выше)
      Все что укажете в блоке default будет применено для всех игроков при респавне в случае, если им не выдан никакой сет!
      Поумолчанию в функции default вызывается функция DefaultSets, позволяющая рандомно выбирать любой из сетов для игроков, которым сет не задан в конфигурации скрипта. Принцип составления сетов такой же, как и выше. Если будете пользоваться этим, обратите вниманием на строку:
      private int random_set_number = Math.RandomIntInclusive(1,6); Эта функция генерирует число от 1 до 6 включительно. Соответственно если сетов будет больше 6, то число надо корректировать и тут тоже!
       
      P.S. Прикрепить к соспавненному оружию магазин не получится, рабочего кода я не смог найти!!
       
      Если у вас папка активной миссии сервера отличается от dayzOffline.chernarusplus то переименуйте ее в строке, вписываемой в:
              {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\init.c
              {папка с вашим сервером}\mpmissions\dayzOffline.chernarusplus\CustomSpawnPlayerConfig\init_mod.c
       
      Благодарности: Товарищу Mizev за его первоначальные гайды в группе VK при появлении в сети серверной части игры
       
       
    • By Akie
      Вопрос в чем, как тому или иному предмету дать свойство, чтобы при использовании в инвентаре он удалялся и давал хумку, пытался сделать сам, сделал удаление предмета через функцию player removeMagazine, потом проверку на количество хумки, то есть, если хумка больше 2500 то _positive, если меньше то _negative, прописал выдачу в зависимости от условия к примеру :
      if (_Positive) then { player setVariable["humanity",(_HumanityVal+5000),true] }; прикрутил экзекут скрипта к Overwrites click actions, кнопка появилась, но при нажатии, ничего не происходит, ни удаления предмета, ни начисления хуманити, куда копать?

      Понимаю, что чего-то не хватает, а вот чего понять не могу, вот сам скрипт:
       
      private ["_item","_HumanityVal","_Negative","_Positive"] _item = "Итем класс нейм"; player removeMagazine _item; _HumanityVal = player getVariable["humanity",0]; if (_HumanityVal <= -2500) then {_Negative = true;}; if (_HumanityVal >= 2500) then {_Positive = true;}; if (_Positive) then { player setVariable["humanity",(_HumanityVal+5000),true] }; if (_Negative) then { player setVariable["humanity",(_HumanityVal-5000),true] }; Подскажите пожалуйста, что не так)
    • By DrTauren
      На нашем сайте предусмотрена возможность рекламирования вашего игрового сервера/сайта/програмного обеспечения при помощи баннеров и ссылок.
       
      Баннеры под первым сообщением темы ↓
       
      Баннер на главной странице (над чатом) ↓
       
      Ссылки над первым сообщением темы ↓
       
      Ссылка на главной странице (над чатом) ↓
       
       

      Заявку вы можете заполнить в этой же теме, либо написать мне в ЛС.
      Любые сообщения не по теме запрещены.
    • By Peresvet
      нипанимайу. как сменить карту на сервере?
    • By BorizzK
      Вот предположим мы создали где-то экземпляр класса;
      ref Class newClass = new Class();
       
      1 Он удалится сам? При каких условиях?
      2 Как его удалить принудительно если он больше не нужен?
       
×
×
  • Create New...

Important Information

By using this site, you automaticly agree to our Guidelines and Privacy Policy.
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.