PDA

Просмотр полной версии : [Мануал] Взрыв машины при попадании по баку



Nexius_Tailer
31.01.2016, 15:13
Приветствую.
Когда копался по старым файлам, нашёл код, который писал ещё для 0.3z - взрыв автомобиля, если попали с огнестрельного оружия по его бензобаку.
Работает, только если машина занята водителем (т.к. существует баг со взрывом незанятого транспорта).
Код проще некуда.

Сейчас мы это разберём:

Итак, в public OnPlayerWeaponShot вставляем следующее:

if(hittype == BULLET_HIT_TYPE_VEHICLE && GetVehicleDriver(hitid) != INVALID_PLAYER_ID)
{
new Float:Offset[3];
GetVehicleModelInfo(GetVehicleModel(hitid), VEHICLE_MODEL_INFO_PETROLCAP, Offset[0], Offset[1], Offset[2]);
if(VectorSize(Offset[0] - fX, Offset[1] - fY, Offset[2] - fZ) <= 0.3)
{
GetVehicleHealth(hitid, Offset[0]);
if(Offset[0])
{
GetVehiclePos(hitid, Offset[0], Offset[1], Offset[2]);
CreateExplosion(Offset[0], Offset[1], Offset[2], 1, 5.0);
SetVehicleHealth(hitid, 0.0);
}
}
}


Куда-нибудь в конец:

stock GetVehicleDriver(vehicleid)
{
for(new i = GetPlayerPoolSize(); i != -1; --i)
{
if(IsPlayerInVehicle(i, vehicleid) && GetPlayerState(i) == PLAYER_STATE_DRIVER) return i;
}
return INVALID_PLAYER_ID;
}


Разжую:
Первое условие проверяет, во что попал игрок. Если он попал в машину и в машине кто-то сидит за рулём, то двигаемся дальше;
Создаём переменные для последующего узнавания координат бензобака, а также узнаём модель машины, в которую попали;
Узнаём координаты бензобака;
Проверяем, насколько далеко от бензобака попал игрок. Если расстояние до бензобака равно либо меньше 0.3 метра (т.е. попал именно в бензобак), идём дальше;
Узнаём хп машины на тот случай, если она уже взорвана (тогда хп будет равняться 0.0);
Проверяем это. Если хп больше 0.0, двигаемся далее;
Узнаём координаты машины для создания взрыва, создаём взрыв на тех координатах, а также ставим машине 0.0 хп.

При следующем выстреле сработает проверка, и если хп у тачки 0.0, то больше машина взрываться не будет.

Функция "GetVehicleDriver" нужна для проверки транспорта на занятость водителем.

Как должно выглядеть в итоге:

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
if(hittype == BULLET_HIT_TYPE_VEHICLE && GetVehicleDriver(hitid) != INVALID_PLAYER_ID)
{
new Float:Offset[3];
GetVehicleModelInfo(GetVehicleModel(hitid), VEHICLE_MODEL_INFO_PETROLCAP, Offset[0], Offset[1], Offset[2]);
if(VectorSize(Offset[0] - fX, Offset[1] - fY, Offset[2] - fZ) <= 0.3)
{
GetVehicleHealth(hitid, Offset[0]);
if(Offset[0])
{
GetVehiclePos(hitid, Offset[0], Offset[1], Offset[2]);
CreateExplosion(Offset[0], Offset[1], Offset[2], 1, 5.0);
SetVehicleHealth(hitid, 0.0);
}
}
}
return 1;
}

stock GetVehicleDriver(vehicleid)
{
for(new i = GetPlayerPoolSize(); i != -1; --i)
{
if(IsPlayerInVehicle(i, vehicleid) && GetPlayerState(i) == PLAYER_STATE_DRIVER) return i;
}
return INVALID_PLAYER_ID;
}


Вроде-бы я этого пока не видел нигде, потому и выложил.

ziggi
31.01.2016, 15:24
Есть одна проблема. Если взорвать транспорт, в котором не сидел игрок, то после рестрима этого транспорта он снова взрывается. И это не исправить (потому что OnVehicleDeath не вызывается).

wAx
31.01.2016, 15:38
Есть одна проблема. Если взорвать транспорт, в котором не сидел игрок, то после рестрима этого транспорта он снова взрывается. И это не исправить (потому что OnVehicleDeath не вызывается).

ну может тогда после взрыва в таймере вызвать SpawnVehicle? или не поможет?

ziggi
31.01.2016, 19:35
ну может тогда после взрыва в таймере вызвать SpawnVehicle? или не поможет?

Можно попробовать.

Nexius_Tailer
31.01.2016, 19:57
ну может тогда после взрыва в таймере вызвать SpawnVehicle? или не поможет?
А, ну тогда можно и вовсе убрать взрыв:


//GetVehiclePos(hitid, Offset[0], Offset[1], Offset[2]);
//CreateExplosion(Offset[0], Offset[1], Offset[2], 1, 5.0);

Всё равно после установки тачке 0 хп она взорвётся. Или я не правильно понимаю, и даже если взрыв будет вызван не CreateExplosion, а SetVehicleHealth, то будет этот баг?
В таком случае можно наоборот, отказаться от SetVehicleHealth :)

Хотя тогда она не будет уничтожена..

Либо, ещё как решение, проверять, занят ли транспорт, и взрывать только если занят.

Daniel_Cortez
31.01.2016, 21:06
Либо, ещё как решение, проверять, занят ли транспорт, и взрывать только если занят.
Возможно, прокатит на несколько миллисекунд телепортировать игрока, запомнив положение его камеры и заблокировав её на прежнем месте, пока игрок не будет телепортирован обратно.

UPD: P.S.: Я этот способ не проверял. И даже не факт, что можно сделать так, чтобы игрок пережил взрыв.

DeimoS
31.01.2016, 22:10
А ещё можно насильно вызвать OnVehicleDeath для взорванного автомобиля :crazy::crazy::crazy::crazy:

P.S. Респавн авто по таймеру поможет. Проверенно на личном опыте. Только есть один минус: пока авто не зареспавнено, у всех, кто был вне зоны стрима, оно будет взрываться при приблежении к нему. Да и у тех, кто был в зоне стрима, тоже, если они отъедут от него и подъедут вновь. А если спавнить с малым интервалом, то можно будет взрывать авто прямо на спавне и обузить это.
Лучший вариант, имхо, либо телепортировать куда-то на время автомобиль, либо менять его интерьер/виртуальный мир после взрыва. Но это уже лучше делать каждому, кто решит взять этот код себе в мод, самостоятельно

Profyan
01.02.2016, 10:09
#offtop
Ох уж эти костыли в Pawn.Ничто так не развивает фантазию, как sa:mp.
По теме:А зачем таймеры нужны и прочее?Сразу зареспавнить транспорт и все?!

DeimoS
01.02.2016, 11:52
#offtop
Ох уж эти костыли в Pawn.Ничто так не развивает фантазию, как sa:mp.
По теме:А зачем таймеры нужны и прочее?Сразу зареспавнить транспорт и все?!

И появится он на том же месте, если был взорван на месте спавна. И выглядеть это будет убого, и начнут опять это же авто взрывать, и и

wAx
02.02.2016, 05:50
Ага. Взрываем авто и через милесекунду оно уже стоит новенькое на месте взрыва (если взорвали на спавне). Мне кажется даже эффект от взрыва не успеет исчезнуть

Profyan
02.02.2016, 10:24
Ну тогда остается вариант с таймером.Перехватить функцию SetVehicleToRespawn и через определенное время уже заспавнить транспорт.Но стоит ли эта система таких костылей?

Daniel_Cortez
02.02.2016, 10:52
Ну тогда остается вариант с таймером.Перехватить функцию SetVehicleToRespawn и через определенное время уже заспавнить транспорт.Но стоит ли эта система таких костылей?
Если спрятать реализацию в инклуде и грамотно организовать код с перехватами, то да, вполне.

DeimoS
03.02.2016, 10:37
Ну тогда остается вариант с таймером.Перехватить функцию SetVehicleToRespawn и через определенное время уже заспавнить транспорт.Но стоит ли эта система таких костылей?

Только это не решит самой проблемы с тем, что у игроков, которые были в момент взрыва далеко, она будет взрываться при приближении :) Тут самый адекватный вариант, это после взрыва авто запускать таймер(секунд на 15 или сколько обычно останки машины после взрыва ещё видны игроку), который телепортирует машину в определённое место, недоступное для игроков и там же запустит ещё один таймер, который уже зареспавнит транспорт обратно. Тогда проблема, описанная выше, будет устранена

SliM
17.02.2016, 12:38
Только это не решит самой проблемы с тем, что у игроков, которые были в момент взрыва далеко, она будет взрываться при приближении :) Тут самый адекватный вариант, это после взрыва авто запускать таймер(секунд на 15 или сколько обычно останки машины после взрыва ещё видны игроку), который телепортирует машину в определённое место, недоступное для игроков и там же запустит ещё один таймер, который уже зареспавнит транспорт обратно. Тогда проблема, описанная выше, будет устранена

если удалить транспорт и создать новый через некоторое время!? Естественно той же модели, цвета и тд.

DeimoS
18.02.2016, 09:17
если удалить транспорт и создать новый через некоторое время!? Естественно той же модели, цвета и тд.
:read::read:

И появится он на том же месте, если был взорван на месте спавна. И выглядеть это будет убого, и начнут опять это же авто взрывать, и и
Хотя если имелось ввиду, что удалять его на то же время, на которое его телепортируем - можно попробовать. Правда не будет ли проблем с тюнингом, если он был на этом транспорте?