Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Need help?

    Create a theme in the appropriate section
    No need to write everything in the chat!
  • Sell or buy?

    Use the services of a guarantor
    We will make your transaction safe
  • Don't want a BAN?

    Please read our rules
    Don't disturb the order
  • Visit the market

    There you can sell or buy
    Everything related to game servers
BorizzK

Выбор точек спавна игроков по UID из файла

Recommended Posts

Как и обещал выкладываю код и небольшой гайд

 

Собственно речь о функции загрузки UID и координат из файла в массив m_playersSpawnPoints класса миссии, который в последствии можно исполдьзовать в других функциях в классе миссии

 

Отступление

массив m_playersSpawnPoints это массив типа map

В данном случае <string,string> где и индекс и значение текстовые строки

индексом выступает записанный UID,  а значением координаты, которые перед использованием преобразуются из текста в vector c помощью функции ToVector()

Но об этом позже

 

Раздел 1. Подключение

 

КОд функции:

	//Players personal spawn points (for new connected players)
	ref map<string,string> m_playersSpawnPoints = new map<string,string>;
	void LoadPlayersSpawnPoints()
	{
		/*
			Файл playersSpawnPoints.lst кладем в папку указанную в параметре запуска сервера -profiles= тогда путь будет "$Profile:"
			или если кладем в файл в mpmissions\dayzOffline.chernarusplus\_CONF путь будет 					"$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"
			Путь меняется в переменной m_SettingsPath - "$Profile:" или "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"
			Можете указать свой путь, но он должен быть либо в $Profiles: либо в $CurrentDir:\\mpmissions\\dayzOffline.chernarusplus
			Формат файла:
			Steam UID в привычном виде 17 цифр Координаты Комментарий (через пробелы)
			Помните любая ошибка может привести к крашу сервера
			Не желательны пустые строки!
			Пример:
			
			76562298156537008 1300 0 5600 Дима
			76561998116927209 3000 0 3000 Вася из Новороссийска
			
			Про массив: ref map<string, string> m_playersSpawnPoints = new map<string, string>;
			m_playersSpawnPoints тут массив типа map, где каждый элемент массива состоит из 2х ячеек.
			1. Индекс - тип string
			2. Значение - тип string
		
			Пример работы с массивом типа map
			Запись в массив
			m_playersSpawnPoints.Insert("76562298156537008", "1300 0 5600"); //записываем первый элемент - индекс dayz, значение 10
			m_playersSpawnPoints.Insert("76561998116927209", "3000 0 3000"); //записываем второй элемент - индекс dayzf, значение 17
			Чтение из массива:
			Получаем значение 0го элемента
			string m = m_playersSpawnPoints.GetElement(0); // = "1300 0 5600"
			Получаем индекс 0го элемента
			string name = m_playersSpawnPoints.GetKey(0); / /= "76562298156537008" 
			Получаем значение по индексу (в данном случае нас интерисует именно ЭТО)
			string n = m_playersSpawnPoints.Get("76561998116927209"); // = "3000 0 3000" //затем n переводим в вектор
			
			Usage in CreateCharacter function for change default spawn position:
			
			string PlayerUID = identity.GetPlainId();
			if (PlayerUID)
			{
				if (m_playersSpawnPoints.Contains(PlayerUID)
				{
					pos = m_playersSpawnPoints.Get(PlayerUID).ToVector();
				}
			}
		*/

		string 			FileName		= "playersSpawnPoints.lst";
		string			m_SettingsPath 	= "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"; //Folder with config files - .ini or .lst // Or "$Profiles:\\"
		FileHandle		file;
		string			file_line;
		array<string> 	read_line;	
		int 			linecount		= 0;	
		
		//Comments check
		bool skipline = false;
		bool skipblock = false;
		//Comments check

		file = OpenFile(m_SettingsPath + FileName, FileMode.READ);
		if (file != 0)
		{
			Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read File: " + m_SettingsPath + FileName + " :::");
			
			while (FGets(file, file_line) >= 0)   
			{
				linecount++;

				//Comments check and skip
				if (file_line.IndexOfFrom(0,"//") == 0 || file_line.IndexOfFrom(0,"#") == 0 || file_line.IndexOfFrom(0," ") == 0 || file_line.Length() <= 0)
				{
					skipline = true;
				}
				else
				{
					skipline = false;
				}
				if (file_line.IndexOfFrom(0,"/*") == 0)
				{
					skipblock = true;
				}
				else if (file_line.IndexOfFrom(0,"*/") == 0)
				{
					skipblock = false;
					skipline = true;
				}
				//Comments check

				if (!skipline && !skipblock)
				{
					read_line = new array<string>;
					file_line.Split(" ",read_line);
					if (read_line.Count() >= 4)
					{
						if (read_line.Get(0).Length() == 17)
						{
							if (read_line.Get(1).ToFloat() > 0 && read_line.Get(3).ToFloat() > 0)
							{
								if (!m_playersSpawnPoints.Contains(read_line.Get(0)))
								{
									m_playersSpawnPoints.Insert(read_line.Get(0), read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3)); // UID, Position
									Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Add UID " + read_line.Get(0) + " spawnpoint: " + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + " to m_playersSpawnPoints");
								}
								else
								{
									Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID " + read_line.Get(0) + " duplicated, check file!");
								}
							}
							else
							{
							Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Position error: '" + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + "' :::");
							}
						}
						else
						{
							Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID error: " + file_line + " :::");
						}
					}
					else
					{
					Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " have errors: " + file_line + " :::");
					}
				}
			}
			CloseFile(file);
			if (m_playersSpawnPoints.Count() > 0)
			{
				Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points count: " + m_playersSpawnPoints.Count() + " :::");
			}
			else
			{
				Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points is not loaded! :::");
			}
		}
		else
		{
			Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Error open file: " + m_SettingsPath + FileName + " :::");
		}
	}

Комментарии, а так же диагностические принты в лог не убираю сознательно

 

ПОдключение и использование.

 

Функцию размещаем в теле класса миссии в init.c или если она вынесена в другой файл (и файл подключени через #include) в том самом файле в теле класса миссии

 

Вот как-то так:

 

class CustomMission : MissionServer
{	

	//Тут разные функции и определение переменных класса...

	//Вот тут переопределенный штатно OnInit 
	override void OnInit ()
	{
      //тут его код
	)


	//Тут определяем наш массив и функцию
	//Players personal spawn points (for new connected players)
	ref map<string,string> m_playersSpawnPoints = new map<string,string>;
	void LoadPlayersSpawnPoints()
	{

		//тут ее код
      
    	}

	//Тут разные функции...

}

 

Ну Вы поняли...

 

Далее нам надо при запуске и инициализации сервера эту функцию выполнить

Но прежде надо создать файл по нужному пути в котором будут UID'ы и координаты

В данной редакции используется путь "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\" и имя файла "playersSpawnPoints.lst"

те в папке mpmissions\dayzOffline.chernarusplus нужно создать папку _CONF и поместить в нее этот файл

Но вы можете это переделать как Вам больше нравится

 

Формат файла:

 

6561198156925007 2698.36 0 5989.59 USER

6561198156924007 2698.36 0 5989.59 ВАСЯ

 

6561198156923007 2698.36 0 5989.59 ПЕТЯ

//Тут комментарий

/*

6561193356923001 3698.36 30 5189.59 ПЕТЯ

*/

 

//Тут комментарий

#Тут комментарий

 

Первое поле - позиция - Это Steam UID (17 цифирь)

2,3,4 поля позиции числа это координаты X Z Y (Z = высота) - если 0 система поставит перса на землю или ближайшую твердую поверхность под ним

все что дальше игнорится

 

Можно каментить строки с помощью // , #

Можно каментить блоки

/*

*/

 

Если первый символ в строке пробел, все остальное то же игнорится

Пустые строки то же игнорятся

 

Если в строке с UID и координатами ошибка об этом напишет в лог с указанием номера строки

Если UID дублируется об этом то же напишет в лог

 

Ок

Файл создали

 

Теперь добавим вызов этой функции в тело функции OnInit в классе миссии (про нее речь шла Выше)

Функция OnInit ВСЕГДА выполняется при запуске сервера

Внутрь мы добавим вызов LoadPlayersSpawnPoints()

В итоге при запуске сервера LoadPlayersSpawnPoints() выполнется и запишет в массив m_playersSpawnPoints UID'ы и координат

 

Добавляем как-то так:

 

	override void OnInit()
	{
		//Тут может быть различный код

		//Тут вызов нашей функции
		//Load players personal spawn poins
		LoadPlayersSpawnPoints(); // => m_playersSpawnPoints // "UID", "Position"

	
		//Тут может быть различный код
	}

 

Запустили  сервер и увидели в логе что файл прочитался и все ок

.... LoadPlayersSpawnPoints() ::: Players personal spawn points count: итд итп

Или ошибки

Если ошибки - читаем все еще раз и/или задаем вопросы в теме (НЕ В ЛИЧКЕ!!!) показывая что куда и как Вы прописали

 

Отлично

Тормозим в сервер

 

Продолжение следует минут через 15

 

 

 

 

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites





Продолжение

 

Раздел 2.

Использование.

 

Поскольку использовать выдачу спавн-точек по UIВ логично при первом подключении игрока к серверу, использовать содержимое массива для

выдачи координат спавна по UID мы будеем в штатной функции сервера/миссии CreateCharacter

 

находим эту функцию в теле класса миссии

 

ее определение выглядит  вот так

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
		//тут код

и добаляем в самом начале код

вот так

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
		if (identity.GetPlainId())
		{
			string p_UID = identity.GetPlainId();
			if (m_playersSpawnPoints.Contains(p_UID))
			{
				vector p_SpawnPoint = m_playersSpawnPoints.Get(p_UID).ToVector();
				Print ("::: init.c ::: PlayerBase CreateCharacter ::: Selected personal spawn point Pos: " + pos.ToString() + " for player: " + identity.GetName() + " with UID: "+ p_UID);
			}
		}
      
      if (p_SpawnPoint) pos = p_SpawnPoint;
	//тут остальной нативный (штатный) код

	}

Что имеем

 

if (identity.GetPlainId()) - проверка на наличие "идентичности" или "личности" подключившегося игрока

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

потом будут ошибки в логе - не красиво

 

string p_UID = identity.GetPlainId(); - получаям Steam UID в привычном виде 17 цифирь

 

if (m_playersSpawnPoints.Contains(p_UID)) - если наш массив m_playersSpawnPoints содержит в индексах UID игрока то

{

    vector pos = m_playersSpawnPoints.Get(p_UID).ToVector(); - перезаписываем содержимое переменной pos (содержащей выданные сервером координаты нового игрока) координатами полученными из массива по UID.

}

 

Вот собственно и все

 

Ну а далее в этой штатной функции идет штатное создание персонажа

 

Отступлю с собьяснением

Entity playerEnt; // определяем переменную в которую попадет персонаж ( "сущность" ) - на самом деле тип Entity то же самое что и EntityAI

playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE"); - создание персонажа - вот тут как раз и указываются координаты создания перса

Class.CastTo(m_player, playerEnt); - кастим сущность из класса EntityAI в переменную m_player класса PlayerBase что бы иметь ссылку на обьект соответствующего класса - странно, но определять тип переменной m_player в данном случае не обязательно

GetGame().SelectPlayer(identity, m_player); - связываем "идентичность/личность" подключившегося игрока с персонажем из переменной m_player

return m_player; - функция возвращает вызвавшему ее ДВИЖКУ ссылку на обьект которым управляет игрок

 

 

Добавлю

можно создавать файлы с любыми конфигами

на основе этого кода читать их в массивы

достаточно просто немного переделать код

 

Есть вопросы? Задавайте

 

Спасибо за внимание...

 

 

 

 

 

 

 

 

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites

Уточню по логике применения скрипта, с Вашего позволения? Т.е. Мне нужно собрать у игроков, которых я хочу спавнить в заданных координатах, их Steam ID, вписать их в массив "playersSpawnPoints.lst", создать файл собственно скрипта, например, Krakozyaba.c , подключить его в init.c через #Include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\Krakozyaba.c" и переопределить функцию CreatCharacter опять таки в init.c ,всё верно? Ничего не упустил?

 

Вопросы: 

1.

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

Теперь добавим вызов этой функции в тело функции OnInit в классе миссии

Это чевой-то? Это нужно вписать функцию в Init.c ? Или я чего-то не догнал?

2. Игроков не прописанных в массив "playersSpawnPoints.lst" это всё никак не задевает? 

 

P.S. Так то, вроде всё выглядит достаточно просто в использовании, даже для меня - а это показатель, поверьте!:biggrin: 

Будем пробовать, огромное спасибо!

Edited by VIRrusR (see edit history)

Share this post


Link to post
Share on other sites

Создать файл lst

Функцию вставить в тело миссии

Вызов функции в функцию oninit в теле миссии

Проверку uid в массиве и запись значения из индекса по uid в переменную pos в функцию createcharacter

 

Если надо, могу переделать функцию в отдельный класс что бы ее проще было подключать. Надо?

Share this post


Link to post
Share on other sites

Добавлю

CreateCharacter уже есть в init.c

В теле класса миссии

Или класс миссии мог быть вынесен в отдельный файл, тогда ищите ее там

 

Ошибочка

Переопределения функции OnInit() в классе миссии по умолчанию нет

 

Надо ее создать в начале тела класса миссии

 

Вот так

 

override void OnInit()

{

    LoadPlayersSpawnPoints();

 super.OnInit();

}

 

Если функция эта уже там есть просто вставляете в ее тело LoadPlayersSpawnPoints();

 

Edited by BorizzK (see edit history)

Share this post


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

Если надо, могу переделать функцию в отдельный класс что бы ее проще было подключать. Надо?

Надо. Удобнее подключать отдельным файлом, а в init.c вписывать только #Include.

И всё же, если Вас не сильно затруднит, как для игроков входящих в список сделать собственный набор стартового лута? То есть обойти то, что прописано в Init.c.

Share this post


Link to post
Share on other sites

VIRrusR А что там обходить?

На основе этого же скрипта

Сделать чтение 1го параметра (UID) из файла и второго там использовать номер сета - остальное игнорить

Далее так же как и выбор координат спавна

только присваивать переменной номер

 

а далее через case комплектовать перса

 

 

Share this post


Link to post
Share on other sites

Не получается... Подозреваю, что init.c неверно оформил, но не пойму где ошибка?

#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\InfoMessages.c"
#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\PlayersMessagesCount.c"
#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\main.c"
void main()
{
	//INIT WEATHER BEFORE ECONOMY INIT------------------------
	Weather weather = g_Game.GetWeather();

	weather.MissionWeather(false);    // false = use weather controller from Weather.c

	weather.GetOvercast().Set( Math.RandomFloatInclusive(0.4, 0.6), 1, 0);
	weather.GetRain().Set( 0, 0, 1);
	weather.GetFog().Set( Math.RandomFloatInclusive(0.05, 0.1), 1, 0);

	//INIT ECONOMY--------------------------------------
	Hive ce = CreateHive();
	if ( ce )
		ce.InitOffline();

	//DATE RESET AFTER ECONOMY INIT-------------------------
	int year, month, day, hour, minute;
	int reset_month = 9, reset_day = 20;
	GetGame().GetWorld().GetDate(year, month, day, hour, minute);

    if ((month == reset_month) && (day < reset_day))
    {
        GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
    }
    else
    {
        if ((month == reset_month + 1) && (day > reset_day))
        {
            GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
        }
        else
        {
            if ((month < reset_month) || (month > reset_month + 1))
            {
                GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
            }
        }
	}
	GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(CustomInformation, TIME_Information_Repeat, true);
	GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(SendPlayersCount, CountPlayers_TIME_InfoPlayers_Repeat, true);
}

class CustomMission: MissionServer
{	
	override void OnInit();
	{
		LoadPlayersSpawnPoints();
		super.OnInit();
	}
	//Players personal spawn points (for new connected players)
	ref map<string,string> m_playersSpawnPoints = new map<string,string>;
	void LoadPlayersSpawnPoints()
	{		
		string 			FileName		= "playersSpawnPoints.lst";
		string			m_SettingsPath 	= "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_CONF\\"; //Folder with config files - .ini or .lst // Or "$Profiles:\\"
		FileHandle		file;
		string			file_line;
		array<string> 	read_line;	
		int 			linecount		= 0;	
		
		//Comments check
		bool skipline = false;
		bool skipblock = false;
		//Comments check

		file = OpenFile(m_SettingsPath + FileName, FileMode.READ);
		if (file != 0)
		{
			Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read File: " + m_SettingsPath + FileName + " :::");
			
			while (FGets(file, file_line) >= 0)   
			{
				linecount++;

				//Comments check and skip
				if (file_line.IndexOfFrom(0,"//") == 0 || file_line.IndexOfFrom(0,"#") == 0 || file_line.IndexOfFrom(0," ") == 0 || file_line.Length() <= 0)
				{
					skipline = true;
				}
				else
				{
					skipline = false;
				}
				if (file_line.IndexOfFrom(0,"/*") == 0)
				{
					skipblock = true;
				}
				else if (file_line.IndexOfFrom(0,"*/") == 0)
				{
					skipblock = false;
					skipline = true;
				}
				//Comments check

				if (!skipline && !skipblock)
				{
					read_line = new array<string>;
					file_line.Split(" ",read_line);
					if (read_line.Count() >= 4)
					{
						if (read_line.Get(0).Length() == 17)
						{
							if (read_line.Get(1).ToFloat() > 0 && read_line.Get(3).ToFloat() > 0)
							{
								if (!m_playersSpawnPoints.Contains(read_line.Get(0)))
								{
									m_playersSpawnPoints.Insert(read_line.Get(0), read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3)); // UID, Position
									Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Add UID " + read_line.Get(0) + " spawnpoint: " + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + " to m_playersSpawnPoints");
								}
								else
								{
									Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID " + read_line.Get(0) + " duplicated, check file!");
								}
							}
							else
							{
							Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " Position error: '" + read_line.Get(1) + " " + read_line.Get(2) + " " + read_line.Get(3) + "' :::");
							}
						}
						else
						{
							Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " UID error: " + file_line + " :::");
						}
					}
					else
					{
					Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Read Line c" + linecount + " have errors: " + file_line + " :::");
					}
				}
			}
			CloseFile(file);
			if (m_playersSpawnPoints.Count() > 0)
			{
				Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points count: " + m_playersSpawnPoints.Count() + " :::");
			}
			else
			{
				Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Players personal spawn points is not loaded! :::");
			}
		}
		else
		{
			Print("::: Init.c ::: LoadPlayersSpawnPoints() ::: Error open file: " + m_SettingsPath + FileName + " :::");
		}
	}
	void SetRandomHealth(EntityAI itemEnt)
	{
		if ( itemEnt )
		{
			int rndHlt = Math.RandomInt(55,100);
			itemEnt.SetHealth("","",rndHlt);
		}
	}

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
		if (identity.GetPlainId())
		{
			string p_UID = identity.GetPlainId();
			if (m_playersSpawnPoints.Contains(p_UID))
			{
				vector p_SpawnPoint = m_playersSpawnPoints.Get(p_UID).ToVector();
				Print ("::: init.c ::: PlayerBase CreateCharacter ::: Selected personal spawn point Pos: " + pos.ToString() + " for player: " + identity.GetName() + " with UID: "+ p_UID);
			}
		}
		Entity playerEnt;
		playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player
		Class.CastTo(m_player, playerEnt);
		
		GetGame().SelectPlayer(identity, m_player);
		
		return m_player;
	}
	
	override void StartingEquipSetup(PlayerBase player, bool clothesChosen)
	{
		EntityAI itemTop;
		EntityAI itemEnt;
		ItemBase itemBs;
		float rand;
		
		itemTop = player.FindAttachmentBySlotName("Body");
		
		if ( itemTop )
		{
			itemEnt = itemTop.GetInventory().CreateInInventory("Rag");
			if ( Class.CastTo(itemBs, itemEnt ) )
				itemBs.SetQuantity(4);

			SetRandomHealth(itemEnt);
			
			itemEnt = itemTop.GetInventory().CreateInInventory("RoadFlare");
			SetRandomHealth(itemEnt);
			
			rand = Math.RandomFloatInclusive(0.0, 1.0);
			if ( rand < 0.35 )
				itemEnt = player.GetInventory().CreateInInventory("Apple");
			else if ( rand > 0.65 )
				itemEnt = player.GetInventory().CreateInInventory("Pear");
			else
				itemEnt = player.GetInventory().CreateInInventory("Plum");
		
			SetRandomHealth(itemEnt);
		}
	}
};
  
Mission CreateCustomMission(string path)
{
	return new CustomMission();
}

Файл "playersSpawnPoints.lst" создал как в примере по пути /serverfiles/mpmissions/dayzOffline.chernarusplus

Собственно, вписал себя:

76561198022615628 10305.0 0 5516.19 Admin

Сервер виснет на загрузке миссии:

19:15:30 PerfWarning: Way too much components (505) in dz\structures\military\improvised\hbarrier_6m.p3d:geometryView
19:15:36 SCRIPT    (E): @"$CurrentDir:mpmissions\dayzOffline.chernarusplus\init.c,50": Unexpected scope

19:15:36 SCRIPT    (E): @"$CurrentDir:mpmissions\dayzOffline.chernarusplus\init.c,51": Unexpected statement 'LoadPlayersSpawnPoints'

19:15:36 SCRIPT    (E): Can't compile mission init script'!

$CurrentDir:mpmissions\dayzOffline.chernarusplus\init.c(50): Unexpected scope

19:17:48 [Disconnect]: Client 34557683 disconnecting

 

Share this post


Link to post
Share on other sites

PJIIOxa , дык он и не запускается. Лог же привёл. На вот это: 

override void OnInit();

{
 LoadPlayersSpawnPoints();
 super.OnInit();
}

плюётся...

Share this post


Link to post
Share on other sites

PJIIOxa , да нет! Всё в Init.c пишем. #Include используется если

21 час назад, BorizzK сказал:

если она вынесена в другой файл (и файл подключени через #include) в том самом файле в теле класса миссии

, чтобы это ни значило... 

Ну, это ж BorizzK... Он же думает, что его кто-то тут способен понять.:biggrin:

Share this post


Link to post
Share on other sites

VIRrusR 

Смотрим нативный (те дефлотный/штатный) ini.c

 


void main()
{
	//INIT WEATHER BEFORE ECONOMY INIT------------------------
	Weather weather = g_Game.GetWeather();

	weather.MissionWeather(false);    // false = use weather controller from Weather.c

	weather.GetOvercast().Set( Math.RandomFloatInclusive(0.4, 0.6), 1, 0);
	weather.GetRain().Set( 0, 0, 1);
	weather.GetFog().Set( Math.RandomFloatInclusive(0.05, 0.1), 1, 0);

	//INIT ECONOMY--------------------------------------
	Hive ce = CreateHive();
	if ( ce )
		ce.InitOffline();

	//DATE RESET AFTER ECONOMY INIT-------------------------
	int year, month, day, hour, minute;
	int reset_month = 9, reset_day = 20;
	GetGame().GetWorld().GetDate(year, month, day, hour, minute);

    if ((month == reset_month) && (day < reset_day))
    {
        GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
    }
    else
    {
        if ((month == reset_month + 1) && (day > reset_day))
        {
            GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
        }
        else
        {
            if ((month < reset_month) || (month > reset_month + 1))
            {
                GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
            }
        }
    }
}

class CustomMission: MissionServer
{	
	void SetRandomHealth(EntityAI itemEnt)
	{
		if ( itemEnt )
		{
			int rndHlt = Math.RandomInt(55,100);
			itemEnt.SetHealth("","",rndHlt);
		}
	}

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
		Entity playerEnt;
		playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player
		Class.CastTo(m_player, playerEnt);
		
		GetGame().SelectPlayer(identity, m_player);
		
		return m_player;
	}
	
	override void StartingEquipSetup(PlayerBase player, bool clothesChosen)
	{
		EntityAI itemTop;
		EntityAI itemEnt;
		ItemBase itemBs;
		float rand;
		
		itemTop = player.FindAttachmentBySlotName("Body");
		
		if ( itemTop )
		{
			itemEnt = itemTop.GetInventory().CreateInInventory("Rag");
			if ( Class.CastTo(itemBs, itemEnt ) )
				itemBs.SetQuantity(4);

			SetRandomHealth(itemEnt);
			
			itemEnt = itemTop.GetInventory().CreateInInventory("RoadFlare");
			SetRandomHealth(itemEnt);
			
			rand = Math.RandomFloatInclusive(0.0, 1.0);
			if ( rand < 0.35 )
				itemEnt = player.GetInventory().CreateInInventory("Apple");
			else if ( rand > 0.65 )
				itemEnt = player.GetInventory().CreateInInventory("Pear");
			else
				itemEnt = player.GetInventory().CreateInInventory("Plum");
		
			SetRandomHealth(itemEnt);
		}
	}
};
  
Mission CreateCustomMission(string path)
{
	return new CustomMission();
}

 

Что видим?

 

Опишу в общем

 

А видим в нем класс миссии который определен так

class CustomMission: MissionServer

 

далее идет открывающая тело скобка (начало кода класса)

{

 

 далее код класса

 те функции которые выполняются в контексте класса миссии сервером

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

 

переопределенные штатные определены как

 

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

{

 код выполняющийся при вызове функции

}

 

можно добавлять свои определив их

например

 

void MyFunction()

{

 int a;

 a = 22;

}

 

 

Далее закрывающая скобка (конец кода класса)

}

 

вот то что внутри {} класса я называю телом класса
а что внутри {} функции телом функции

 

 

так вот

Класс можно вытащить в  отдельный файл вот так

 

создаем по пути

Диск:\Папка сервера\mpmissions\dayzOffline.chernarusplus\_MISSION

файл MissionAD.c

клпируем весь класс в этот файл

в самом init.c этот класс удаляем

 

в начале файла init.c вставляем подключение того файла

#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_MISSION\\MissionAD.c"

 

вот сам файл MissionAD.c

там только класс перенесенный из init.c

class CustomMission: MissionServer
{	
	void SetRandomHealth(EntityAI itemEnt)
	{
		if ( itemEnt )
		{
			int rndHlt = Math.RandomInt(55,100);
			itemEnt.SetHealth("","",rndHlt);
		}
	}

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
		Entity playerEnt;
		playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player
		Class.CastTo(m_player, playerEnt);
		
		GetGame().SelectPlayer(identity, m_player);
		
		return m_player;
	}
	
	override void StartingEquipSetup(PlayerBase player, bool clothesChosen)
	{
		EntityAI itemTop;
		EntityAI itemEnt;
		ItemBase itemBs;
		float rand;
		
		itemTop = player.FindAttachmentBySlotName("Body");
		
		if ( itemTop )
		{
			itemEnt = itemTop.GetInventory().CreateInInventory("Rag");
			if ( Class.CastTo(itemBs, itemEnt ) )
				itemBs.SetQuantity(4);

			SetRandomHealth(itemEnt);
			
			itemEnt = itemTop.GetInventory().CreateInInventory("RoadFlare");
			SetRandomHealth(itemEnt);
			
			rand = Math.RandomFloatInclusive(0.0, 1.0);
			if ( rand < 0.35 )
				itemEnt = player.GetInventory().CreateInInventory("Apple");
			else if ( rand > 0.65 )
				itemEnt = player.GetInventory().CreateInInventory("Pear");
			else
				itemEnt = player.GetInventory().CreateInInventory("Plum");
		
			SetRandomHealth(itemEnt);
		}
	}
}

 

А вот новый init.c

 

#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_MISSION\\MissionAD.c"

void main()
{
	//INIT WEATHER BEFORE ECONOMY INIT------------------------
	Weather weather = g_Game.GetWeather();

	weather.MissionWeather(false);    // false = use weather controller from Weather.c

	weather.GetOvercast().Set( Math.RandomFloatInclusive(0.4, 0.6), 1, 0);
	weather.GetRain().Set( 0, 0, 1);
	weather.GetFog().Set( Math.RandomFloatInclusive(0.05, 0.1), 1, 0);

	//INIT ECONOMY--------------------------------------
	Hive ce = CreateHive();
	if ( ce )
		ce.InitOffline();

	//DATE RESET AFTER ECONOMY INIT-------------------------
	int year, month, day, hour, minute;
	int reset_month = 9, reset_day = 20;
	GetGame().GetWorld().GetDate(year, month, day, hour, minute);

    if ((month == reset_month) && (day < reset_day))
    {
        GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
    }
    else
    {
        if ((month == reset_month + 1) && (day > reset_day))
        {
            GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
        }
        else
        {
            if ((month < reset_month) || (month > reset_month + 1))
            {
                GetGame().GetWorld().SetDate(year, reset_month, reset_day, hour, minute);
            }
        }
    }
}

Mission CreateCustomMission(string path)
{
	return new CustomMission();
}

 

Так понятно???
Как по другому обьяснить я не представляю

 

Добавлю

Фигурные скобки { } используюся для тела классов, функций и некоторых массивов

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

 

В любом  коде кол-во открывающих { и закрывающих фигурных скобок } всегда одинаковое кол-во

То же касается и обычных кобок ( )

 

Ну кроме случая когда Вы используете их в комментариях и диагностических принтах (вовод в лог) - там же Вы можете использовать одну {

Потому я их там не использую и для обозначения/выделения чего-то в комментариях и выводе в лог использую квадратные скобки [ ]

 

 

 

Edited by BorizzK (see edit history)

Share this post


Link to post
Share on other sites

VIRrusR PJIIOxa 

 

Господа

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

в определении класса и функций в конце ; не ставится

 

должно быть

 

override void OnInit()

 

у Вас же override void OnInit();

 

Сорри - мой косяк в посте выше - где код был вне тега  кода

 

как-то так машинально получилось

 

класс ща выложу

Share this post


Link to post
Share on other sites

 

BorizzK , погодите, пощадите, пожалуйста, дедушку!..:joy:

Дайте понять и переварить информацию... 

Т.е. Init.c приведённый мной верный? Всё дело в синтаксической ошибке:

class CustomMission: MissionServer
{	
	override void OnInit();
	{
		LoadPlayersSpawnPoints();
		super.OnInit();
	}
Edited by VIRrusR (see edit history)

Share this post


Link to post
Share on other sites

VIRrusR у меня вот как прописано, сервер стал запускаться только вот точки спавна не работают я суицид делаю нажимаю реснуться и появляюсь серавно на берегу

override void OnInit () 
	{	
	    LoadPlayersSpawnPoints(); // => m_playersSpawnPoints // "UID", "Position"
		super.OnInit();
		SetClothes();
	}

 

Share this post


Link to post
Share on other sites

А должно быть:

class CustomMission: MissionServer
{	
	override void OnInit()
	{
		LoadPlayersSpawnPoints();
		super.OnInit();
	}

Извините, но не получилось предыдущий пост отредактировать почему-то... 

Я верно понимаю?

Edited by VIRrusR (see edit history)

Share this post


Link to post
Share on other sites

BorizzK  у меня вот как прописано, сервер стал запускаться только вот точки спавна не работают я суицид делаю нажимаю реснуться и появляюсь серавно на берегу

override void OnInit () 
	{	
	    LoadPlayersSpawnPoints(); // => m_playersSpawnPoints // "UID", "Position"
		super.OnInit();
		SetClothes();
	}

 

Share this post


Link to post
Share on other sites

VIRrusR дак так и прописано просто когда вставляю на сайте он почему то сдвигает строчку override void OnInit ()

Share this post


Link to post
Share on other sites

Обещанный класс во вложении

Подключаете этот файл через include (как обычно)

#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_MOD\\SpawnPoints\\SpawnPointsClass.c" //Server_SpawnPoints_Class

 

Следующей строкой определяем ссылку на класс - у нас она будет Server_SpawnPoints

ref Server_SpawnPoints_Class Server_SpawnPoints = new Server_SpawnPoints_Class();
 

В коде это выглядит так

#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\_MOD\\SpawnPoints\\SpawnPointsClass.c" //Server_SpawnPoints_Class
ref Server_SpawnPoints_Class Server_SpawnPoints = new Server_SpawnPoints_Class();

 

Инициализировать в OnInt() его не нужно

Те если Вам OnInt() не нужен для каких-то других целей из миссии его убираем

 

При определении класса выполнится его конструктор (см код класса - там есть каменты) и в нем вызов LoadPlayersSpawnPointsByUid();

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

 

Использовать в функции CreateCharacter класса миссии так:

 

		vector p_SpawnPoint = Server_SpawnPoints.GetPlayerSpawnPoint(identity); //See Server_SpawnPoints_Class
		if (p_SpawnPoint)
		{
			pos = p_SpawnPoint;
			Print ("::: init.c ::: PlayerBase CreateCharacter ::: Selected personal spawn point: Pos: " + pos.ToString() + " for player: " + identity.GetName() + " with UID: " + identity.GetPlainId());
		}

 

Обьяснение

 

vector p_SpawnPoint = Server_SpawnPoints.GetPlayerSpawnPoint(identity);

 

Тут мы одновременно определяем переменную типа vector

этот тип может содержать в себе координаты в виде <X Z Y> где X Z Y это числа типа float (с плавающей точкой) 2222.34 333.2 и тп
X - широта
Z - высота над уровнем моря
Y - долгота

(Координаты мест можно посмотреть на izurvive dayz map)

 

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

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

Server_SpawnPoints.GetPlayerSpawnPoint

 

Однако можно и не определять ссылку на класс и не использовать определение ссылки:

ref Server_SpawnPoints_Class Server_SpawnPoints = new Server_SpawnPoints_Class();

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

 

тогда к функции GetPlayerSpawnPoint из этого класса можно обратиться так

Server_SpawnPoints_Class.GetPlayerSpawnPoint

 

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

функции  CreateCharacter и содержит в себе ссылку на сущность подключающегося игрока

 

вобщем после такого вызова

vector p_SpawnPoint = Server_SpawnPoints.GetPlayerSpawnPoint(identity);

 

в переменную SpawnPoint попадут координаты из файла если они соответствуют UID

если такового в файле нет то функция вернет "0 0 0"

И код в условии  if (p_SpawnPoint) выполнен не будет и в переменной pos  которая так же является входной переменной функции

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

 

если же в SpawnPoint попадут координаты  и условие будет выполнено

переменная pos будет перезаписана координатами из переменной p_SpawnPoint

pos = p_SpawnPoint;

и персонаж будет создан по указанной координате

 

собственно новый код функции  CreateCharacter

 

	override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
	{
      	//Координаты по UID
		vector p_SpawnPoint = Server_SpawnPoints.GetPlayerSpawnPoint(identity); //See Server_SpawnPoints_Class
		if (p_SpawnPoint)
		{
			pos = p_SpawnPoint;
			Print ("::: init.c ::: PlayerBase CreateCharacter ::: Selected personal spawn point: Pos: " + pos.ToString() + " for player: " + identity.GetName() + " with UID: " + identity.GetPlainId());
		}
      	//Координаты по UID

        Entity playerEnt;
		playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player
		Class.CastTo(m_player, playerEnt);
		
		GetGame().SelectPlayer(identity, m_player);
		
		return m_player;
	}

 

Надеюсь все всё поняли ))))

 

 

 

 

 

 

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Share this post


Link to post
Share on other sites

PJIIOxa а в логе что?

Удали все .log в папке сервера

Запусти

Убейся

Зайди

Скинь script.log сюда

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Similar Content

    • By 123new
      За основу взята наработка автора скрипта: http://s-platoon.ru/profile/14721-borizzk/
      И немного доработана по своим соображениям.
      Использование мода клиенту игры НЕ ТРЕБУЕТСЯ!!!
       
      И так, установка:
      1. Первым делом нам необходим чистый стандартный сервер DayZ (без модов, поскольку моды могу приводить к неработоспособности частей гайда). Установить его можно по инструкции, например, так:
      2. Добавляем в папку сервера игры мод из архива:
      3. Добавляем в параметры запуска сервера:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      -Filepatching "-servermod=@KillFeed_ServerMod" Если ваш сервер уже имеет серверные моды, просто добавьте папку с модом в список используемых сервером модов.
      ВАЖНО: не добавляйте данный мод в параметр запуска сервера -mod=, иначе это может стать проблемой заходи игроков с параметрами verifysignatures=2; equalmodrequired=1;
      4. В 'config-файле' сервера (там где названием сервера и прочие настройки) добавляем настройки для мода:
      //KillFeed_mod KillFeed_enableSaveKills = 1; // Включение сохранения счетчика убийств по игрокам KillFeed_enableSaveDies = 1; // Включение сохранения счетчика смертей по игрокам KillFeed_enableCustomTimeLog = 1; // Включение записи модом 'Кастомных' логов смертей игроков KillFeed_enableDefaultLog = 1; // Включение записи сервером стандартных логов сервера в scripts.log KillFeed_enableDebugLog = 1; // Включение записи сервером отладочных логов сервера в scripts.log (работает при KillFeed_enableDefaultLog = 1) KillFeed_enableMessages = 1; // Включение отправки сообщений в чат сервера о смертях игроков Пояснения к настройкам, как видите, имеются.
      Напомню, активный профиль сервера обозначается параметром '-profiles={имя папки или путь до папки}'
      Например, при указании:
      -profiles=Instance_1 папка профиля сервера будет выглядеть вот так:
      5. Запускаем сервер, умираем от зомби и радуемся. Сообщения о смертях игроков будут в чате у других игроков (если в настройках игры они не отключены), так и в script.log.

      Где хранятся счетчики убийств и смертей? Ответ:
      Они хранятся в profile сервера игры. Т.е. после 1-го запуска создаются 2 файла (как у клиента игры в документах windows в папку dayz) в файлах с расширениями ".vars.DayZProfile" и ".DayZProfile". При удалении этих файлов счетчики сбросятся!
       
      P.S. Чтобы увидеть сообщения в чате, нужно быть 2-м игрокам на сервере, и умереть одному из двух. тот, кто умирает, сообщения с чата не видит!!!
       
    • By AntonivkA
      Итак, господа. В 1.05 разрабы похоже сломали механику спавна лута. У меня предметы стали спавниться там, где их не должно быть. Заметил сразу, поскольку таблица лута у меня переделана основательно. Например, Песочный барьер у меня прописан только на Военках и Полиц.участке, и все работало корректно до 1.05. Теперь, песочный барьер я нахожу в гаражах, мастерских и жилых домах вокруг полиц. участка и в самом полиц. участке. Помимо этого, ребята стали замечать и скинули инфу, что на СЗ в гаражах и мастерских стал появлятся военный лут, хотя его там не должно быть.
      Кто-что скажет по этому поводу. Заметил ли кто-то подобное у себя?
       
    • By mafan9
      Здравствуйте! Как отключить выбор пола в ESS v3? Спасибо
    • By Karmagedon
      Всем привет! Ребят. Подскажите где кавырнуть что бы к примеру определенный вид оружия спавнился только на тисах! Заранее спасибо!
    • By PJIIOxa
      Help! очень нужен скрипт отдельным файлом на экипировку для определенных игроков по UID.
×
×
  • 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.