PDA

Просмотр полной версии : [Вопрос] Алгоритм фиксирования HP автомобиля



punkochel
24.01.2020, 00:41
Друзья, мне необходимо составить наиболее эффективный и наименее затратный алгоритм фиксирования HP автомобиля.
Наверняка многие из вас играли на Role Play серверах и там при повреждении автомобиля до определенного уровня HP, он якобы ломался.
Я сделал подобную систему через OnVehicleDamageStatusUpdate, но изначально было понятно что она не будет работать как нужно. Так как в колбэке имеются возвращаемые vehicleid and playerid мы сможем узнавать HP автомобиля, но к сожалению не сможем получать урон при ударе об стену (конечно можно использовать глобальную переменную и создать некую формулу).
Даже если вопрос с уроном решить костыльным (на мой взгляд) способом, то колбэк OnVehicleDamageStatusUpdate кажется не срабатывает когда по автомобилю наносят урон с оружия (но это не точно) следовательно необходимо получать и записывать HP автомобиля в таймере, но опять же возникает следующая проблема, а именно то что когда автомобиль якобы сломался и далее по нему нанесли еще какой-то урон, то автомобиль снова якобы сломается (видно будет на примере мою мысль), то есть он никогда не взорвется, хотя по моей идее он должен уже загореться и взорваться, это можно исправить используя переменную с булевым значением (но это опять костыль...).
То бишь подведем итог: мне необходимо сделать так, чтобы когда HP автомобиля достигала менее 300 единиц, то автомобиль ломался, а если уже по поломанному автомобилю нанесли еще урон - он взрывался.
То что было сделано мною ранее:

vehicle_OnVehicleDamageStatusUp(vehicleid, playerid)
{
new Float:carhp, engine,lights,alarm,doors,bonnet,boot,objective;
GetVehicleHealth(vehicleid, carhp);
if(carhp > 0 && carhp < 300)
{
GameTextForPlayer(playerid,"~r~ENGINE DAMAGED", 3000, 3);
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective);
SetVehicleParamsEx(vehicleid,false,false,alarm,doors,bonnet,boot,objective);
SetVehicleHealth(vehicleid, 300.0);
}
return 1;
}

DeimoS
24.01.2020, 01:27
Немного кривоватый код у тебя. Вот:
vehicle_OnVehicleDamageStatusUp(vehicleid, playerid)
{
static Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
GetVehicleHealth(vehicleid, carhp);
if(carhp <= 300.0)
{
GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
if(engine == VEHICLE_PARAMS_ON)
{
GameTextForPlayer(playerid,"~r~ENGINE DAMAGED", 3000, 3);
SetVehicleParamsEx(vehicleid, false, false, alarm, doors, bonnet, boot, objective);
SetVehicleHealth(vehicleid, 300.0);
}
}
return 1;
}
Как вариант. Ну либо, как ты сам написал, переменную. По другому тут никак и не сделать.

red.inc
24.01.2020, 10:33
DeimoS. static - Они инициализируются только один раз - при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.

Я как понял, у него ид транспорта каждый раз меняется. В этом случае, лучше использовать new.

punkochel
24.01.2020, 11:41
Немного кривоватый код у тебя. Вот:
vehicle_OnVehicleDamageStatusUp(vehicleid, playerid)
{
static Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
GetVehicleHealth(vehicleid, carhp);
if(carhp <= 300.0)
{
GetVehicleParamsEx(vehicleid, engine, lights, alarm, doors, bonnet, boot, objective);
if(engine == VEHICLE_PARAMS_ON)
{
GameTextForPlayer(playerid,"~r~ENGINE DAMAGED", 3000, 3);
SetVehicleParamsEx(vehicleid, false, false, alarm, doors, bonnet, boot, objective);
SetVehicleHealth(vehicleid, 300.0);
}
}
return 1;
}
Как вариант. Ну либо, как ты сам написал, переменную. По другому тут никак и не сделать.

И в самом деле, все оказалось проще пареной репы) Спасибо за помощь! Я то уже начал какие-то сложно-костыльные способы придумывать))
А что если по автомобилю будет нанесен урон с оружия, Callback вызовется?



DeimoS. static - Они инициализируются только один раз - при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.

Я как понял, у него ид транспорта каждый раз меняется. В этом случае, лучше использовать new.

Да, именно так vehicleid будет каждый раз другой, но static просто создает переменные в сегменте данных а не в стеке, как это было-бы с new. По сути между new и static нет никакой разницы, просто new создается во время выполнения и удаляется по завершению функции, а при повторном вызове они снова создаются и инициализируются в отличии от static, static сохраняет данные предыдущего выполнения.

DeimoS
24.01.2020, 11:51
DeimoS. static - Они инициализируются только один раз - при первом вызове функции и сохраняют свое значение даже после выхода из функции. В следующий раз при новом вызове функции статические переменные будут иметь то же значение, которое они имели перед выходом из функции в послений раз.

Я как понял, у него ид транспорта каждый раз меняется. В этом случае, лучше использовать new.

Если ты посмотришь внимательнее, то увидишь, что у него каждая переменная всякий раз сначала записывает определённое значение из функций и только потом используется (а ID авто - это вообще параметр функции, а не переменная). Так что все сохранённые значения от предыдущего вызова функции будут перезаписаны актуальными.
OnVehicleDamageStatusUpdate вызывается довольно часто на заполненном игроками сервере, ибо постоянно кто-то где-то катается и бьётся. И смысл static, в данном случае, в том, чтоб не тратить лишнее время на инициализацию переменных. Мы тратим чуть больше памяти, но выигрываем немного времени для частовызываемой функции. Как итог, мы получим больше пользы от выигранного времени, нежели если бы мы сократили использование сегмента данных и продолжили использовать стек.


А что если по автомобилю будет нанесен урон с оружия, Callback вызовется?

Скорее всего нет. Точно не помню, так что перепроверь.
Вообще гораздо проще поместить этот код в таймер обновления спидометра. Там всё равно обычно бывает вызов функции GetVehicleHealth для отображения состояния авто в спидометре, что можно использовать для реализации этого кода.

punkochel
24.01.2020, 12:02
Скорее всего нет. Точно не помню, так что перепроверь.
Вообще гораздо проще поместить этот код в таймер обновления спидометра. Там всё равно обычно бывает вызов функции GetVehicleHealth для отображения состояния авто в спидометре, что можно использовать для реализации этого кода.

Спасибо за идею!)

red.inc
24.01.2020, 16:15
Хм. static записывает в себе значение car_hp, engine;
Если выходить из функции, то vehicleid и playerid, будет содержать сохранения hp автомобиля и производить изменения не будет, там самым, игрок получается ударился 1 раз и его ХП сохранится в памятие и изменяться больше не будет, исходя из vehicleid и ид игрока. И после получение второго урона проверка не пройдет. Также в дальнейшем - изменятся он не будет.

Может я что-то не так понял. Но услышать вариант также хочется.

- - - Добавлено - - -

Хотя. Ты верно говоришь, перечитал твой комментарий

L0ndl3m
24.01.2020, 20:00
DeimoS (https://pro-pawn.ru/member.php?2548), почему используется static, вместо new в данном случае?

geneff
24.01.2020, 23:52
L0ndl3m, он уже ответил на этот вопрос выше

Daniel_Cortez
25.01.2020, 00:27
DeimoS. static - Они инициализируются только один раз - при первом вызове функции
Не инициализируются они ни при каком вызове функции. Их изначальное значение рассчитывается ещё на этапе компиляции скрипта (и именно поэтому при объявлении к ним можно присвоить только константу или константное выражение, но никак не значение переменной или результат из функции) - проще говоря, они уже инициализированы заранее.