123new
А с чего Вы решили, коллега, что я не выложу в эту самую тему итоговый вариант своего решения вопроса?! Я где-то такое сказал? Просто итоговое решение, ещё нужно реализовать.
Вам нравится цитировать собственные "удачные" высказывания? (Мне, кстати, да, даже очень!)
Я где-то высказал какие-то претензии по поводу того, что Вы или кто-либо ещё предложили не то решение?! Или плохое решение? Я лишь высказался, что конкретно Ваш вариант лично мне, в данный момент, применительно к моей задаче не совсем подходит, ибо мне не нужна сложная система градации урона по степени повреждения костюма. Это вас как-то оскорбило?! В таком случае, примите мои искренние извинения!
Да. Никто не станет. Более того, никто иной как Вы, мне очень доступно объяснили, выписав штрафные баллы (нисколько не оспариваю и не возражаю - нарушил, выписывайте), что просьба "сделать" - противоречит правилам данного ресурса. Ну правила - это наше (Ваше?) всё! Нельзя, значит нельзя. Будете наказывать меня за однажды допущенное нарушение ежедневно? Или личное обращение с просьбой "научить делать" - тоже нарушает какое-то из Священных Правил? Нет?.. Ну тогда в чём проблема? Я обратился к толковому человеку и он согласился научить, за что я ему бесконечно благодарен.
Ну это уж!.. "Мою пасочку сломал, песочком в глазки насыпал... Сам дурак!.. Собирай свои игрушки и не писай в мой горшок!.."
Вы это всё вообще серьёзно?! Давайте сочтём это просто дружеской пикировкой? Со своей стороны обещаю и торжественно клянусь, что никогда и ни за что не буду даже пытаться как-то "похохмить" в общении с Вами - всё только строго официально и в формулировках не допускающих возможности какого-либо второго, (про третье я даже заикаться не хочу - чур меня, чур!) толкования.
Ещё раз благодарю! Совершенно верно - решение почти готовое. На данный момент времени "почти" для меня не преодолимо, но я над этим работаю. Такая реализация мне не нужна для практического применения, но я обязательно постараюсь её понять и опробовать - для обучения. Ещё раз спасибо!
Это как посмотреть: с точки зрения создания работающего варианта заражённых зон с проверкой на наличие и целостность комплекта ОЗК - да. Код создан:
class Zone {
int id;
int type;
vector pos;
float radius;
}
enum ZoneType {
SAFE,
GAS,
RAD,
BIO
}
ref array<ref Zone> ga_zones = new array<ref Zone>;
ref ControllerZones ctrl_zones = new ControllerZones;
class ControllerZones {
void ControllerZones() {
int id = 0;
vector pos;
float radius;
int type = 0;
id = 1; // Pavlovo
pos = "2125 0 3400";
radius = 200.0;
AddZone(id, pos, radius);
id = 2; // Zeleno
pos = "2530 0 5112";
radius = 150.0;
AddZone(id, pos, radius);
id = 3; // Dichina
pos = "4524 0 8290";
radius = 50.0;
AddZone(id, pos, radius);
id = 4; // Mushkino
pos = "1150 0 7235";
radius = 100.0;
AddZone(id, pos, radius);
id = 5; // Aero SW
pos = "4586 0 9533";
radius = 220.0;
AddZone(id, pos, radius);
id = 6; // Aero SE
pos = "5177 0 9960";
radius = 350.0;
AddZone(id, pos, radius);
id = 7; // Aero W
pos = "4228 0 10400";
radius = 350.0;
AddZone(id, pos, radius);
id = 8; // Aero E
pos = "4785 0 10530";
radius = 250.0;
AddZone(id, pos, radius);
id = 9; // Aero N
pos = "4290 0 10956";
radius = 250.0;
AddZone(id, pos, radius);
id = 10; // Tisy
pos = "1600 0 14030";
radius = 600.0;
AddZone(id, pos, radius);
id = 11; // Troitskoe
pos = "7893 0 14689";
radius = 300.0;
AddZone(id, pos, radius);
id = 12; // Aero NN
pos = "4035 0 11700";
radius = 250.0;
AddZone(id, pos, radius);
GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(CheckZones, 5000, true);
}
void ~ControllerZones() {
}
void AddZone(int id, vector pos, float radius, int type = ZoneType.BIO) {
ref Zone zone = new ref Zone;
zone.id = id;
zone.pos = pos;
zone.radius = radius;
zone.type = type;
ga_zones.Insert(zone);
}
bool InZone(PlayerBase player, ref Zone zone) {
vector player_position = player.GetPosition();
player_position[1] = 0;
if( (vector.Distance(player_position, zone.pos)) < zone.radius )
{
EntityAI attachment;
ItemBase item;
float biosafe = 0;
attachment = player.FindAttachmentBySlotName("Mask");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("GP5GasMask") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
attachment = player.FindAttachmentBySlotName("Headgear");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("NBCHoodGray") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
attachment = player.FindAttachmentBySlotName("Body");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("NBCJacketGray") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
attachment = player.FindAttachmentBySlotName("Legs");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("NBCPantsGray") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
attachment = player.FindAttachmentBySlotName("Feet");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("NBCBootsGray") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
attachment = player.FindAttachmentBySlotName("Gloves");
if ( attachment && attachment.IsItemBase() )
{
item = ItemBase.Cast(attachment);
if ( item.GetType().Contains("NBCGlovesGray") && ((item.GetHealth()) > 40) )
{
biosafe = biosafe + 1.0;
}
}
if ( biosafe > 5.0 )
return true;
float damage_player;
float damage_zone = 6.0;
damage_player = player.GetHealth("GlobalHealth", "Health");
player.SetHealth("GlobalHealth", "Health", damage_player - (damage_zone - ((damage_zone / 6) * biosafe)));
player.GetSymptomManager().QueueUpPrimarySymptom(SymptomIDs.SYMPTOM_COUGH);
player.GetSymptomManager().QueueUpPrimarySymptom(SymptomIDs.SYMPTOM_VOMIT);
Param1<string> m_MessageParam = new Param1<string>("Оденьте ОЗК и ПРОТИВОГАЗ!!!");
GetGame().RPCSingleParam(player, ERPCs.RPC_USER_ACTION_MESSAGE, m_MessageParam, true, player.GetIdentity());
return true;
}
return false;
}
void CheckZones() {
ref array<Man> players = new array<Man>;
GetGame().GetPlayers( players );
for ( int i = 0; i < players.Count(); i++ )
{
PlayerBase player;
Class.CastTo(player, players.Get(i));
for ( int j = 0; j < ga_zones.Count(); j++ ) {
if(InZone(player, ga_zones.Get(j))) {
break;
}
}
}
}
}
Вставляете приведённый выше код в созданный Вами .c -файл, например main.c
В init.c прописываете самой первой строкой подключение данного файла содержащего скрипт:
#include "$CurrentDir:\\mpmissions\\dayzOffline.chernarusplus\\main.c"
Логика работы: Если игрок входит в одну из заражённых зон, то осуществляется проверка на наличие полного комплекта ОЗК и противогаза, а также, проверяется каждый элемент защитного костюма на наличие повреждений (статус "Повреждено"). В случае отсутствия или повреждения любого из элементов защитного костюма, игрок получает урон по здоровью. При вхождении в зону заражения без полного защитного костюма, либо в костюме, имеющем повреждение хотя бы одного элемента, выводится сообщение о необходимости надеть костюм ОЗК и противогаз. Нанесение урона игроку сопровождается следующими симптомами:
-- кашель
-- рвота
Весь процесс моих стараний от исходного варианта до существующего на данный момент времени, Вы сможете найти в указанной ранее теме.
P.S. Вариант считаю не окончательным,в виду примитивности реализации. Тем не менее, вариант вполне работоспособный и в данный момент, используется мной на моём сервере.
P.P.S. Благодарю BorrizK - за пошаговые объяснения логики работы, принципов построения и синтаксиса скриптов. Огромное Человеческое спасибо! 123new - за помощь в обнаружении ошибки, препятствовавшей нормальной работе скрипта, а кроме того, за освоение метода логирования и понимание его необходимости - искреннее спасибо! elanc - за исходный срипт "заражённых зон", явившийся основой для данного решения и послуживший мне учебником - большое спасибо!