Counter-Strike: Scripting Amx Mod X - продвинутый уровень

Scripting Amx Mod X - основы
Рассмотрим часть моего полного плагина, которая отвечает за восстановление здоровья при падении(скачать можно в разделе CS):
» код плагина без частей, рассмотренных в статьи(ч. 1)
/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <amxmisc>
#include <csx>
#include <fun> 
#pragma tabsize 0
#define PLUGIN "Health Control"
#define VERSION "1.0"
#define AUTHOR "Artte@xgm.ru(jabber)"

new torestore=50
new StoredHealth[33]={0,...}
new ToRestoreHealth[33]={0,...}

public plugin_init() {
register_cvar("hctrl_reshpvalue","0")
register_cvar("hctrl_resonfall","0")
set_cvar_num("hctrl_resonfall",0)
set_cvar_num("hctrl_reshpvalue",50)
torestore=get_cvar_num("hctrl_reshpvalue")
register_event("Damage","onfall","be", "2!0")
set_task(0.2,"StoreHealth",0,"",0,"b",0)
}
 
public StoreHealth() 
{
new i=0
while (++i<=get_maxplayers())
{
StoredHealth__=get_user_health(i)
}
return PLUGIN_CONTINUE
}

public restore(id)
{
new hp=get_user_health(id)
torestore=get_cvar_num("hctrl_reshpvalue")
if (torestore+hp>=ToRestoreHealth[id]) 
{
set_user_health(id,ToRestoreHealth[id]) 
} else {
set_user_health(id,hp+torestore)
}
set_hudmessage(150,250,100,1.0,1.0,0,3.0,5.0,0.1,0.2,4)
show_hudmessage(id,"Restored %i health",get_user_health(id)-hp)
return PLUGIN_CONTINUE
}

public onfall(victim) 
{ 

new str3
str3=read_data(4)
new str4
str4=read_data(5)
new str5
str5=read_data(6)
if (str3==0 && str4==0 && str5==0 && get_cvar_num("hctrl_resonfall")==1) 
{
set_task(1.0,"restore",victim,"",0,"a",1)
ToRestoreHealth[victim]=StoredHealth[victim]

}
return PLUGIN_CONTINUE
}

Начнем с разбора задачи

Суть:
Игрок падает, через 1 секунду ему восстанавливается x здоровья(при условии, что падение отняло больше x-1), иначе здоровье восстанавливается до значения, равного здоровью до падения. При этом в любом случае конечное здоровье не должно превышать значение 100.
Реализация:
Что нам надо знать для выполнения задачи? Поразмыслив, разумный человек прийдет к выводу, что ему нужно знать несколько вещей: значение здоровья до падения, на сколько восстанавливать(х) и кому восстанавливать. Чтож, подумаем над тем, как узнать здоровье до падения. Я скажу заранее, что в момент получения любого урона нельзя узнать значение здоровья до его получения прямо из функции, которая сработает при событии получения урона. Поэтому логичным решением является таймер. Значения мы будем сохранять в массив, в котором id игроков будут служить индексами. Однако подумайте, ведь за 1 секунду наш таймер с малым периодом может перезаписать значение здоровья на полученное после падения... эту проблему решаем следующим образом: создаем параллельный массив, в который будем записывать ПРИ ПАДЕНИИ здоровье, которое нужно восстановить. Далее, через 1 секунду мы восстановим здоровье. "А как мы его восстановим?" - спросите вы: таймер, такой же таймер решит нашу проблему. Хороший плюс языка PAWN в том, что есть уникальные id таймеров, котоыре можно передавать в исполняемые ими функции, чем мы и воспользуемся. Приступим к написанию кода!
Я буду описывать каждый участок кода наиболее доступным образом:
Начало
new torestore=50 переменная, из которой будет браться значение для восстановления хп
new StoredHealth[33]={0,...} Сюда записываем здоровье
new ToRestoreHealth[33]={0,...} А это наш параллельный массив, из которого будем брать значение хп

public plugin_init() {
register_cvar("hctrl_reshpvalue","0") регистрируем переменную CVAR, определяющую значение восстанавливаемого хп
register_cvar("hctrl_resonfall","0") регистрируем CVAR, отвечающую за работоспособность всей идеи, т.е. восстановление можно будет просто отключить\включить
set_cvar_num("hctrl_resonfall",0)      устанавливаем
set_cvar_num("hctrl_reshpvalue",50) им значения
torestore=get_cvar_num("hctrl_reshpvalue") 
register_event("Damage","onfall","be", "2!0") Регистрируем событие Damage для функции onfall с флагами "be"(обычный набор флагов для события) и с условием 2!0, т.е. значения 0 и 2, которые передаст функция не должны равняться друг другу(т.е. урон не равен нулю, ибо 2-й параметр есть урон)
set_task(0.2,"StoreHealth",0,"",0,"b",0) создаем таймер, который будет записывать значение хп всех игроков каждые 0,2 секунды. флаг b означает что таймер бесконечный
}
Функция записи хп

public StoreHealth() 
{
new i=0
while (++i<=get_maxplayers()) обычный цикл, записываем хп всех игроков в массив
{
StoredHealth__=get_user_health(i)
}
return PLUGIN_CONTINUE
}
Функция события Damage

public onfall(victim) 
{ 

new str3
str3=read_data(4)
new str4
str4=read_data(5)
new str5
str5=read_data(6)
          тут мы считали данные- координаты источника повреждений. при падении они все равны нулю. Хотя, такое же условие можно указать и в самом событии через запятую(помните 2!0 ?) !
if (str3==0 && str4==0 && str5==0 && get_cvar_num("hctrl_resonfall")==1) Не забываем првоерить включено ли наше действие
{
set_task(1.0,"restore",victim,"",0,"a",1) Тут мы создаем таймер на 1 сек, на функцию restore и даем таймеру уникальный id-id жертвы(помните я говорил что это нам понадобится?), флаг "а" означает что таймер одноразовый.
ToRestoreHealth[victim]=StoredHealth[victim] И опять же, наш параллельный массив, записываем в него значение хп, которое, кстати, находится во временном промежутке [время падения-0.2 ; время падения)

}
return PLUGIN_CONTINUE
}
Функция восстановления хп

public restore(id) не забываем принять уникальный id таймера!
{
new hp=get_user_health(id) хп после падения
torestore=get_cvar_num("hctrl_reshpvalue") вспоминаем на сколько надо восстановить
if (torestore+hp>=ToRestoreHealth[id]) условия, описанные нами намного выше
{
set_user_health(id,ToRestoreHealth[id]) 
} else {
set_user_health(id,hp+torestore)
}
set_hudmessage(150,250,100,1.0,1.0,0,3.0,5.0,0.1,0.2,4) Вывод сообщения, подробнее ниже
show_hudmessage(id,"Restored %i health",get_user_health(id)-hp)
return PLUGIN_CONTINUE
}
Теперь рассмотрим вывод сообщения на экран:
(hud-сообщение - цветное соообщение в любой точке экрана)

set_hudmessage(150,250,100,1.0,1.0,0,3.0,5.0,0.1,0.2,4) Здесь мы задаем параметры всех hud сообщений(принимаемые параметры смотрите в AMX STUDIO, т.к. описывать их достаточно долго), поэтому перед выводом своих сообщений обязательно перенастраивайте все параметры!
show_hudmessage(id,"Restored %i health",get_user_health(id)-hp) Собственно, вывод сообщения. Кому и что вывести. %i значит, что на эт оместо вставится число типа integer из параметров(get_user_health(id)-hp)
На этом всё, теперь вы можете спокойно создавать свои уже непростые плагины!

Просмотров: 3 508

Комментарии пока отсутcтвуют