В данной теме я распишу мой вариант установки сейвзоны, работающий на момент публикации статьи на версии сервера игры 1.06.152885.
Установка
1. Открываем 'init.c' в 'MpMissions' вашей.
2. Вверху файла добавляем 1 строкой:
#include "$CurrentDir:\\mpmissions\\dayzoffline.chernarusplus\\Scripts\safezone.c"
Где 'dayzoffline.chernarusplus' - имя папки с активной 'MpMissions' вашей.
Т.е. для карты Livonia 'dayzoffline.chernarusplus' надо вручную заменить на 'dayzOffline.enoch'
Пример:
3.Создаем папку 'Scripts' в корне 'MpMissions' вашей, а в ней создаем файл с именем 'safezone.c' следующего содержания:
/*
Author: Sania(ZoS) (aka 123new)
Project: S-platoon.ru
Install:
1. Create a 'Scripts' directory in your active mpmissions
2. Plase this filename (safezone.c) in 'Scripts'
3. Add in init.c this line:
#include "$CurrentDir:\\mpmissions\\dayzoffline.chernarusplus\\Scripts\safezone.c"
Where is 'dayzoffline.chernarusplus' is active mpmission directory in cfg filename server
4. Configure a next settings
*/
class SafeZone_PlugIn
{
protected bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)
protected float SAFEZONE_time_repeat_checking = 10; //In seconds
ref static TStringArray SAFEZONE_LOACTIONS = {"15145.1 32.9793 13919.0",
"12145.1 32.9793 10919.0"};//Map coords (positions of the safe zone)
protected static float SAFEZONE_RADIUS = 100; //In meter
protected static string SAFEZONE_ENTRY_MESSAGE = "Welcome to The SafeZone! Godmode ENABLED!";
protected static string SAFEZONE_EXIT_MESSAGE = "You Have Left The SafeZone! Godmode DISABLED!";
void OnInit()
{
if(Activate_SafeZone_PlugIn)
{
GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(RunCheckStart, (SAFEZONE_time_repeat_checking * 1000), true);
}
}
static void RunCheckStart()
{
private array<Man> players = new array<Man>;
GetGame().GetPlayers( players );
if (SAFEZONE_LOACTIONS.Count() > 0)
{
if (players.Count() > 0)
{
foreach(string SAFEZONE_LOACTION: SAFEZONE_LOACTIONS)
{
if( players.Count() > 0 )
{
foreach(Man player: players)
{
if(player)
{
private PlayerBase player_casted = PlayerBase.Cast(player);
CheckingPosition(player_casted,SAFEZONE_LOACTION.ToVector());
}
}
}
}
}
}
}
static void CheckingPosition(PlayerBase player,vector SAFEZONE_LOACTION)
{
private float SAFEZONE_distance;
private string SAFEZONE_ZoneCheck, SAFEZONE_UID_PLAYER, SAFEZONE_NAME_PLAYER;
SAFEZONE_NAME_PLAYER = player.GetIdentity().GetName();
SAFEZONE_UID_PLAYER = player.GetIdentity().GetPlainId(); //Steam 64
private vector SAFEZONE_pos_player = player.GetPosition();
private vector SAFEZONE_LOCATION_FIXED = CorrectToGroundPosY(SAFEZONE_LOACTION);
private string name_mesage_profile = "GodModeEnabledFor: " + SAFEZONE_UID_PLAYER + " Location: " + SAFEZONE_LOACTION.ToString();
SAFEZONE_distance = vector.Distance(SAFEZONE_pos_player,SAFEZONE_LOCATION_FIXED);
if (SAFEZONE_distance <= SAFEZONE_RADIUS) //Player Inside Zone
{
SAFEZONE_ZoneCheck = "";
GetGame().GetProfileString(name_mesage_profile,SAFEZONE_ZoneCheck);
if (SAFEZONE_ZoneCheck == "true") //Already in zone
{
GetGame().SetProfileString(name_mesage_profile,"true");
player.SetAllowDamage(false); //GodMode On
return;
}
else
{
GetGame().SetProfileString(name_mesage_profile,"true");
Print("[SafeZone] " + SAFEZONE_NAME_PLAYER + " (" + SAFEZONE_UID_PLAYER + ") Enter in safeZone in position: " + SAFEZONE_LOCATION_FIXED.ToString());
player.SetAllowDamage(false); //GodMode On
SendPersonalMessage(SAFEZONE_ENTRY_MESSAGE, player);
}
} else
{
//Player Outside of Zone
if (SAFEZONE_distance > SAFEZONE_RADIUS) //Player Outside of Zone
{
SAFEZONE_ZoneCheck = "";
GetGame().GetProfileString(name_mesage_profile,SAFEZONE_ZoneCheck);
if (SAFEZONE_ZoneCheck == "false")
{
GetGame().SetProfileString(name_mesage_profile,"false");
return;
}
else
{
if (SAFEZONE_ZoneCheck != "")
{
GetGame().SetProfileString(name_mesage_profile,"false");
Print("[SafeZone] " + SAFEZONE_NAME_PLAYER + " (" + SAFEZONE_UID_PLAYER + ") Left safeZone in position: " + SAFEZONE_LOCATION_FIXED.ToString());
player.SetAllowDamage(true); //GodMode Off
SendPersonalMessage(SAFEZONE_EXIT_MESSAGE, player);
} else
{
GetGame().SetProfileString(name_mesage_profile,"false");
return;
}
}
}
}
}
static vector CorrectToGroundPosY(vector pos)
{
private float pos_x = pos[0];
private float pos_z = pos[2];
private float pos_y = GetGame().SurfaceY(pos_x, pos_z);
private vector tmp_pos = Vector(pos_x, pos_y, pos_z);
return tmp_pos;
}
static void SendPersonalMessage(string message, PlayerBase casted_player)
{
Man player;
Class.CastTo(player, casted_player);
if(( player ) && (message != ""))
{
Param1<string> m_GlobalMessage = new Param1<string>(message);
GetGame().RPCSingleParam(player, ERPCs.RPC_USER_ACTION_MESSAGE, m_GlobalMessage, true, player.GetIdentity());
}
}
}
/*
class SafeZone_Config //test config for json
{
vector SAFEZONE_LOACTION = "15145.1 32.9793 13919.0"; //Map coords (position of the safe zone)
float SAFEZONE_RADIUS = 100.0; //In meter
string SAFEZONE_ENTRY_MESSAGE = "Welcome to The SafeZone! Godmode ENABLED!";
string SAFEZONE_EXIT_MESSAGE = "You Have Left The SafeZone! Godmode DISABLED!";\
}
*/
ref SafeZone_PlugIn SafeZone = new SafeZone_PlugIn();
modded class CustomMission
{
override void OnInit ()
{
super.OnInit();
SafeZone.OnInit();
}
}
Ну или скачиваем его отсюда в готовом виде: safezone.c
Здесь:
'SAFEZONE_LOACTIONS' - координаты точкек центра сейвзоны, можно указать несколько.
'SAFEZONE_RADIUS' - радиус от указанного центра севзоны, на котором действует защита
'ENTRY_MESSAGE' - сообщение о входе в зону (не рекоммендуется указывать русский язык, может не отображаться)
'EXIT_MESSAGE' - сообщение о выходе из зоны (не рекоммендуется указывать русский язык, может не отображаться)
'SAFEZONE_time_repeat_checking' - время повтора проверки наличия игроков в зонах, в секундах
'Activate_SafeZone_PlugIn' - активация плагина скрипта, true - ключен, false - выключен
4. Запускаем сервер и проверяем.
Для совсем ленивых готовая миссия сервера с настроенной сейвзоной для патча игры 1.06 dayzOffline.chernarusplus.rar
Гайд обновлен: 31.01.2020