Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

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

Статус
В этой теме нельзя размещать новые ответы.

q0b3rMAN

Умник
Создание разрушаемых объектов или объектов, которые могут быть повреждены.
​

Вступление

Всем привет,
Совсем недавно, была выпущена версия SA-MP 0.3z. Благодаря ей, появилась возможность более удобной синхронизации и проверку на стрельбу в игрока, автомобиль и даже - объект. Ну, и поскольку такое возможно, то наверняка можно такое сделать, а почему бы и нет, верно? Ведь только 0.3z обеспечивает такую функцию.

Примечание: Я знаю, что данная версия еще "сырая", однако, этот мануал работает без каких-либо ошибок.

Примечание 2: На данный момент я хочу объяснить лишь то, что объекты могут разрушаться или уничтожаться только(!) с помощью "CreateObject" или "CreatePlayerObject". А еще отлично то, что Стример был обновлен до версии 0.3z, поэтому работать будет еще легче.

Требования



  • Серверные файлы SA-MP 0.3z RC2
  • Стример версии 0.3z
?

Общее понятие

Сама концепция состоит в том, что объект будет поврежден или уничтожен. Уничтожение объектов будет происходить, естественно, без всякой логики, но сама система продумана до мельчайших деталей. Так же чуть не забыл, если вы хотите чтобы объекты уничтожались, они должны быть созданы только с помощью скриптовой части PAWN, если вы думаете, что сможете уничтожить встроенные в движок GTA:SA объекты, вы - ошиблись.

Мануал

Давайте-ка приступим к самому уроку. Прежде всего, откройте самое главное - pawno.exe и убедитесь в том, что у вас включен инклуд a_samp.
PHP:
#include <a_samp>

  • Создание переменной HP для каждого объекта.

Если вы уже не терпите продолжить, то мы конечно же, продолжим. На данный момент необходимо объявить переменную HP для наших объектов.
PHP:
new ObjectHP[MAX_OBJECTS]; //Мы объявили переменную для 1000 объектов. (MAX_OBJECTS = 1000)
Теперь, давайте создадим некоторые объекты и назначим их HP. В этом мануале, я собираюсь показать создание объектов на примере Filterscript.
PHP:
#define FILTERSCRIPT

#include <a_samp>

  • Создание объектов.
?
Само создание объектов довольно просто, ведь с ним справится даже новичок в PAWNО. Вы можете использовать как функцию "CreateObject", так и ручная расстановка объектов с помощью самых примитивных Мап-эдиторов. Я, конечно же, выбрал второй способ, поскольку это удобнее и легче. В мануале, я рассмотрю пять мною созданных объектов в аэропорту Лос Сантоса.

Примечание: Я хочу сказать вам то, что лучше всего использовать те объекты, которые не разрушаются по умолчанию. Например, вы создадите обычный металлический столб и въедете в него на машине, что с ним произойдет? Конечно же он разрушится мгновенно.

Перед, так скажем, "внедрением" объектов в наш Filterscript, необходимо сбросить HP для объектов, а после их создания, установить HP обратно.

PHP:
#include <a_samp>

new ObjectHP[MAX_OBJECTS];

public OnFilterScriptInit()
{
    //Сбросим все HP через цикл.
    for(new i; i< MAX_OBJECTS; i++) ObjectHP[i] = 0;
    /* Максимум 1000 объектов.
    Выглядит примерно так:
    ObjectHP[0] = 0;
    ObjectHP[1] = 0;
    ObjectHP[2] = 0;
    ...
    ObjectHP[999] = 0; */
    CreateObject(18848, 1450.59, -2446.57, 12.50,   0.00, 0.00, 0.00);
    CreateObject(18848, 1442.11, -2444.87, 12.55,   0.00, 0.00, 0.00);
    CreateObject(18848, 1461.18, -2446.89, 12.54,   0.00, 0.00, 0.00);
    CreateObject(18848, 1457.31, -2430.67, 12.54,   0.00, 0.00, 0.00);
    CreateObject(18848, 1449.48, -2430.51, 12.54,   0.00, 0.00, 0.00);
    //Я создал пять нерушимых объектов
    //Теперь, настроим им HP.
    for(new i; i< MAX_OBJECTS; i++) { //Опять тот же цикл.
         if(!IsValidObject(i)) continue; /* Если объект не рабочий, пропускаем и идем дальше.
         */
         ObjectHP[i] = 100; //Сделаем 100 хп для более быстрого разрушения.
    }
    return 1;

}
Примечание: Это самый оптимальный способ для создания объектов и установки HP.


  • Повреждение объектов.

?
В версии 0.3z стрельба всегда называлась "OnPlayerWeaponShot". А поскольку у нас 0.3z RC2, то он поддерживает более легкий способ.
OnPlayerWeaponShot можно вызвать так:
PHP:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
 return 1;
playerid - Стрелок.
weaponid - Оружие используемое при выстреле.
hittype - Тип выстрела. (см. далее)

В GTA существует несколько видов выстрелов.

PHP:
#define BULLET_HIT_TYPE_NONE                0
#define BULLET_HIT_TYPE_PLAYER              1
#define BULLET_HIT_TYPE_VEHICLE             2
#define BULLET_HIT_TYPE_OBJECT              3
#define BULLET_HIT_TYPE_PLAYER_OBJECT   4
BULLET_HIT_TYPE_NONE вызывается если игрок не стреляет.
BULLET_HIT_TYPE_PLAYER вызывается если игрок стреляет в игрока.
BULLET_HIT_TYPE_VEHICLE вызывается если игрок стреляет в автомобиль.
BULLET_HIT_TYPE_OBJECT вызывается если игрок стреляет в объект.
BULLET_HIT_TYPE_PLAYER_OBJECT вызывается если игрок стреляет в созданный объект.

hitid
hitid
является ID связанным с hittype. В случае, если hittype будет TYPE_PLAYER, то он вернет ID игрока, он будет hitid. Если это автомобиль, то он вернет ID автомобиля как hitid. Тоже самое будет с TYPE_OBJECT и TYPE_PLAYER_OBJECT.

Fx, Fy, Fz
Координаты игрока или машины откуда был произведен урон.

Мы и будем использовать эту функцию для уменьшения HP объекта или его уничтожения.

PHP:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    //Мы должны знать, прошел урон, или нет.
    if(hittype == BULLET_HIT_TYPE_OBJECT) { //В случае, если игрок попадает в объект
        if(IsValidObject(hitid)) {
            ObjectHP[hitid] -= random(10) + 1;
            if(ObjectHP[hitid] <= 0) { //Если у объекта HР меньше нуля или 0
                DestroyObject(hitid);
            }
        }
    }
    return 1;
}
Нет, мы еще не закончили. Мы сделали лишь половину нашей работы, а именно - концепция уничтожения объекта. Чтобы все это выглядело немного лучше, мы можем сделать некоторую информацию насчет HP объекта. Код ниже и будет это выполнять.

PHP:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    //Мы должны знать, прошел урон, или нет.
    if(hittype == BULLET_HIT_TYPE_OBJECT) { //В случае, если игрок попадает в объект
        if(IsValidObject(hitid)) {
            ObjectHP[hitid] -= random(10) + 1;
            if(ObjectHP[hitid] >= 0) { //Если HP объекта либо 0, либо 1.
                new str[128]; //Нужно вывести строку для отображения сообщения.
                //Я буду использовать GameTextForPlayer, потому что SendClientMessage будет сильно спамить.
                format(str, sizeof(str), "~G~OBJECT DAMAGED!~N~~Y~OBJECT ID ~W~: ~R~ %d~N~~Y~HP LEFT ~W~: ~R~ %d", hitid, ObjectHP[hitid]);
                //Покажем ID объекта и его HP.
                GameTextForPlayer(playerid, str, 1800, 3);
                //Для отображения сообщения игрока, я буду использовать "3", потому что это самое лучшее для частого вывода сообщения.
            }
            if(ObjectHP[hitid] <= 0) { //Если у объекта HР меньше нуля или 0
                DestroyObject(hitid);
            }
        }
    }
    return 1;
}


  • Полный результат с вышеупомянутым.
?
PHP:
#define FILTERSCRIPT

#include <a_samp>

new ObjectHP[MAX_OBJECTS];

public OnFilterScriptInit()
{
    //Сбросим все HP через цикл.
    for(new i; i< MAX_OBJECTS; i++) ObjectHP[i] = 0;
    /* Максимум 1000 объектов.
    Выглядит примерно так:
    ObjectHP[0] = 0;
    ObjectHP[1] = 0;
    ObjectHP[2] = 0;
    ...
    ObjectHP[999] = 0; */
    CreateObject(18848, 1450.59, -2446.57, 12.50,   0.00, 0.00, 0.00);
    CreateObject(18848, 1442.11, -2444.87, 12.55,   0.00, 0.00, 0.00);
    CreateObject(18848, 1461.18, -2446.89, 12.54,   0.00, 0.00, 0.00);
    CreateObject(18848, 1457.31, -2430.67, 12.54,   0.00, 0.00, 0.00);
    CreateObject(18848, 1449.48, -2430.51, 12.54,   0.00, 0.00, 0.00);
    //Я создал пять нерушимых объектов
    //Теперь, настроим им HP.
    for(new i; i< MAX_OBJECTS; i++) { //Опять тот же цикл.
         if(!IsValidObject(i)) continue; /* Если объект не рабочий, пропускаем и идем дальше.
         */
         ObjectHP[i] = 100; //Сделаем 100 хп для более быстрого разрушения.
    }
    return 1;

}

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    //Мы должны знать, прошел урон, или нет.
    if(hittype == BULLET_HIT_TYPE_OBJECT) { //В случае, если игрок попадает в объект
        if(IsValidObject(hitid)) {
            ObjectHP[hitid] -= random(10) + 1;
            if(ObjectHP[hitid] >= 0) { //Если HP объекта либо 0, либо 1.
                new str[128]; //Нужно вывести строку для отображения сообщения.
                //Я буду использовать GameTextForPlayer, потому что SendClientMessage будет сильно спамить.
                format(str, sizeof(str), "~G~OBJECT DAMAGED!~N~~Y~OBJECT ID ~W~: ~R~ %d~N~~Y~HP LEFT ~W~: ~R~ %d", hitid, ObjectHP[hitid]);
                //Покажем ID объекта и его HP.
                GameTextForPlayer(playerid, str, 1800, 3);
                //Для отображения сообщения игрока, я буду использовать "3", потому что это самое лучшее для частого вывода сообщения.
            }
            if(ObjectHP[hitid] <= 0) { //Если у объекта HР меньше нуля или 0
                DestroyObject(hitid);
            }
        }
    }
    return 1;
}
На этом, с повреждениями закончено. Следующим шагом является передовой метод, который включает в себя другой тип повреждения.


  • Групповой метод.
?
В сгруппированном методе, мы задаем лишь те объекты для разрушения, которые нам нужны. Для начала, нам нужно объявить переменную "ObjectHP".

PHP:
#define FILTERSCRIPT

#include <a_samp>

new ObjectHP[MAX_OBJECTS];
Теперь мы можем объявить другую переменную, чтобы проверить, получает объект повреждения или нет. Это позволит вам повредить только те объекты, которые нам нужны, ведь они находятся в списке. Так как остальные повреждены не будут, функция вызываться не будет.


PHP:
new bool:ObjectDamage[MAX_OBJECTS]; //Зададим два состояния.
//Я буду использовать это так, как двойную переменную. Получение / не получение урона.
PHP:
#define FILTERSCRIPT

#include <a_samp>

new ObjectHP[MAX_OBJECTS],
    bool:ObjectDamage[MAX_OBJECTS];

public OnFilterScriptInit()
{
    //Сбросим все HP через цикл.
    for(new i; i< MAX_OBJECTS; i++) {
        ObjectHP[i] = 0;
        /*Максимум 1000 объектов.
        Выглядит примерно так:
        ObjectHP[0] = 0;
        ObjectHP[1] = 0;
        ObjectHP[2] = 0;
        ...
        ObjectHP[999] = 0; */

        //В групповом методе я так же сбрасываю их HP.
        ObjectDamage[i] = false;
        /* Цикл выполняется так:
        ObjectDamage[0] = false;
        ObjectDamage[1] = false;
        ObjectDamage[2] = false;
        ...
        ObjectDamage[3] = false; */
    }
    /*
    Массив для получения объектов */
    new Object_ID[5]; //5 объектов, следовательно массив из 5.
    Object_ID[0] = CreateObject(18848, 1450.59, -2446.57, 12.50,   0.00, 0.00, 0.00);
    Object_ID[1] = CreateObject(18848, 1442.11, -2444.87, 12.55,   0.00, 0.00, 0.00);
    Object_ID[2] = CreateObject(18848, 1461.18, -2446.89, 12.54,   0.00, 0.00, 0.00);
    Object_ID[3] = CreateObject(18848, 1457.31, -2430.67, 12.54,   0.00, 0.00, 0.00);
    Object_ID[4] = CreateObject(18848, 1449.48, -2430.51, 12.54,   0.00, 0.00, 0.00);
    //Я создал пять нерушимых объектов и сгруппировал их.
    //ТЕперь, настроим их HP.
    //На этот раз, установим HP только для них(!).
    //Задаем:
    for(new i; i< 5; i++) {
        ObjectDamage[Object_ID[i]] = true;
        /*Делаем урон быстрым образом :
        ObjectDamage[Object_ID[0]] = true;
        ObjectDamage[Object_ID[1]] = true;
        ...
        ObjectDamage[Object_ID[4]] = true; */
    }
    //Теперь я устанавливаю HP как раньше.
    //Но, я устанавливаю их только на нужные:
    for(new i; i< MAX_OBJECTS; i++) {
        if(!IsValidObject(i)) continue;
        if(ObjectDamage[i] == false) continue;
        ObjectHP[i] = 100;
    }
    return 1;
}
Итак, я сгруппировал их, теперь сделаем так, чтобы они получали урон при какой-либо попытке разрушения.


PHP:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    if(hittype == BULLET_HIT_TYPE_OBJECT) {
        if(IsValidObject(hitid)) {
            if(ObjectDamage[hitid] == true) {

                ObjectHP[hitid] -= random(10) + 1;
                if(ObjectHP[hitid] >= 0) {
                    new str[128];
                    format(str, sizeof(str), "~G~OBJECT DAMAGED!~N~~Y~OBJECT ID ~W~: ~R~ %d~N~~Y~HP LEFT ~W~: ~R~ %d", hitid, ObjectHP[hitid]);
                    GameTextForPlayer(playerid, str, 1800, 3);
                }
                if(ObjectHP[hitid] <= 0) {
                    DestroyObject(hitid);
                }
            }

        }
    }
    return 1;
}
В коде я установил шесть объектов, но только пять из них могут быть уничтоженными, потому что я сгруппировал их в отдельности от шестого.


  • Объекты стримера.

?
Это довольно легко, ведь поменять парочку строчек дано каждому. "CreateObject" меняется на "CreateDynamicObject" и "OnPlayerWeaponShot" на "OnPlayerShootDynamicObject". Но все таки я напишу полный код.

PHP:
public OnPlayerShootDynamicObject(playerid, weaponid, objectid, Float:x, Float:y, Float:z)
{
        //objectid возвращает ID объекта который получил урон.
        if(IsValidDynamicObject(objectid)) { //Динамический объекты известны как "IsValidDynamicObject".
            if(PlayerObjectDamage[playerid][objectid] == true) { //Если наносит повреждения:
                PlayerObjectHP[playerid][objectid] -= random(10) + 1;
                if(PlayerObjectHP[playerid][objectid] >= 0) { //Если HР больше 0;
                    new str[128]; //Концепция вообще-то не нужна, но нам нужна информация.
                    format(str, sizeof(str), "~G~DAMAGE DONE!~N~~Y~PLAYER OBJECT ID ~W~: ~R~ %d~N~~Y~HP LEFT ~W~: ~R~ %d", hitid, PlayerObjectHP[playerid][hitid]);
                    GameTextForPlayer(playerid, str, 1800, 3);
                }
                if(PlayerObjectHP[playerid][objectid] <= 0) {
                    DestroyDynamicObject(objectid); //Уничтожили объект.
                }
            }
        }
    }
    return 1;
}
Ну вот и все, конец урока, вроде ничего не забыл. Задавайте свои вопросы, предлагайте что то дополнить или убрать, удачи.
 
Последнее редактирование модератором:
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу