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)
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;
}
- Повреждение объектов.
?В версии 0.3z стрельба всегда называлась "OnPlayerWeaponShot". А поскольку у нас 0.3z RC2, то он поддерживает более легкий способ.
OnPlayerWeaponShot можно вызвать так:
PHP:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
return 1;
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_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;
}
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;
}
Последнее редактирование модератором:
