Код
#include <amxmodx>
#include <fakemeta>
#include <reapi>
// ********************************************************************************
*********** //
//#define ADMIN_FLAG ADMIN_BAN // игроки с этим флагом могут возрождать тиммейтов ВЫКЛ это и смогут все
#define TIME 5 // сколько идет процесс самой реинкарнации? (в секундах)
#define ROUND_TIME 15.0 // через сколько секунд от начала раунда будет работать (ВЫКЛ будет всегда)
#define SPEED 170.0 // скорость игрока в это время ВЫКЛ и будет неизменной
//#define MAX 5 // сколько может максимально воскресить 1 игрок за раунд ВЫКЛ будет неограничено
//#define MAX_USER 3 // сколько может максимально воскреснуть игрок за раунд ВЫКЛ будет неограничено
#define MAX_DISTANCE 130.0 // максимальная допустимая дистанция
#define FLOOD 2.0 // через сколько можно использовать вновь (защита от флуда)
#define NEW_HP 50.0 // здоровье только воскрешенного игрока ВЫКЛ будет 100 как всегда
//#define COST 1000 // стоимость услуги ВЫКЛ бесплатно
#define BAR // полоска прогресса? вкл\выкл
#define SPAWN // воскрешённый игрок спавнится там где умер, ВЫКЛ будет на спавне
#define NOTIFY // уведомления в чат кто кого воскресил?
// позволяет заминировать туп врага, при попытке воскресить его - враг взорвется
// настройки сверху также распространяются и на это
#define ENEMY_MODE
//#define SOUNDS // вкл\выкл звуки событий (обязательно укажите путь)
//#define API // api
// ********************************************************************************
*********** //
#if defined ENEMY_MODE
#include <hamsandwich>
//#define KILL_EFFECT // эффект при убийстве
#endif
new const __BODY_CLASSNAME[] = "__its_dead";
enum _:__nolkfun
{
__g_iPlayerIndexEntity,
#if defined MAX
__g_ReviveCount,
#endif
#if defined MAX_USER
__g_ReviveMax,
#endif
#if defined ENEMY_MODE
__g_IsBoomPlayer,
#endif
Float:__g_fDelay
}; new __g_PlayersData[MAX_PLAYERS + 1][__nolkfun];
#if defined API
enum _:__Forwards
{
__Fw_Return,
__Fw_Revived,
__Fw_Mined,
}; new __gForwards[__Forwards];
#endif
stock const __g_bPrefix[] = "^4[NOLKFUN]^1"; // тег в чате
#define __TASK_REVIVE 100
#define __ID_REVIVE (__taskid - __TASK_REVIVE)
#define StartRevive(%1) (set_entvar(%1, var_iuser2, 1))
#define StopRevive(%1) (set_entvar(%1, var_iuser2, 0))
#define IsReviving(%1) (get_entvar(%1, var_iuser2) == 1)
#define __IsValidTeam(%1) (TEAM_TERRORIST <= get_member(%1, m_iTeam) <= TEAM_CT)
#if defined SOUNDS
new const __g_bSoundRevive[] = ""; // звук при завершении возрождения
new const __g_bSoundMining[] = ""; // звук при завершении минирования
public plugin_precache()
{
precache_sound(__g_bSoundRevive);
precache_sound(__g_bSoundMining);
}
#endif
public plugin_init()
{
register_plugin("__[ReAPI] Can Revive Players", "1.0.0", "NOLKFUN");
register_forward(FM_CmdStart, "__fw_CmdStart");
RegisterHookChain(RG_CSGameRules_CleanUpMap, "__CSGameRules_CleanUpMap_Post", true);
#if defined SPEED
RegisterHookChain(RG_CBasePlayer_ResetMaxSpeed, "__CBasePlayer_ResetMaxSpeed_Post", true);
#endif
register_message(get_user_msgid("ClCorpse"), "__MsgHookClCorpse");
#if defined API
__gForwards[__Fw_Revived] = CreateMultiForward("rt_revived", ET_IGNORE, FP_CELL, FP_CELL);
__gForwards[__Fw_Mined] = CreateMultiForward("rt_mined", ET_IGNORE, FP_CELL, FP_CELL);
#endif
}
public __fw_CmdStart(__id, __uc_handle)
{
if (!is_user_alive(__id)) return;
#if defined ADMIN_FLAG
if (~get_user_flags(__id) & ADMIN_FLAG) return;
#endif
#if defined ROUND_TIME
if (get_gametime() - Float:get_member_game(m_fRoundStartTime) < ROUND_TIME) return;
#endif
if (get_uc(__uc_handle, UC_Buttons) & IN_USE && ~pev(__id, pev_oldbuttons) & IN_USE && !__g_PlayersData[__id][__g_iPlayerIndexEntity]) __start_revive(__id);
else if (pev(__id, pev_oldbuttons) & IN_USE && ~get_uc(__uc_handle, UC_Buttons) & IN_USE && __g_PlayersData[__id][__g_iPlayerIndexEntity]) __stop_revive(__id);
}
public __CSGameRules_CleanUpMap_Post()
{
new __iEnt = rg_find_ent_by_class(NULLENT, __BODY_CLASSNAME);
while (__iEnt > 0)
{
set_entvar(__iEnt, var_flags, FL_KILLME);
__iEnt = rg_find_ent_by_class(__iEnt, __BODY_CLASSNAME);
} for (new i; i < sizeof(__g_PlayersData); i++) arrayset(__g_PlayersData[i], 0, __nolkfun);
}
__start_revive(__id)
{
if ( get_member_game(m_bRoundTerminating) || __g_PlayersData[__id][__g_fDelay] > get_gametime() ) return;
#if defined MAX
if (__g_PlayersData[__id][__g_ReviveCount] >= MAX)
{
client_print_color(__id, print_team_red, "%s ^3вы не можете воскрешать/минировать более^4 %d раз", __g_bPrefix, MAX);
return;
}
#endif
#if defined COST
if (get_member(__id, m_iAccount) < COST) return;
#endif
if (__g_PlayersData[__id][__g_iPlayerIndexEntity]) __stop_revive(__id);
new __iEnt = NULLENT, __iPlayer, Float:__fOrigin[3]; get_entvar(__id, var_origin, __fOrigin);
while ((__iEnt = engfunc(EngFunc_FindEntityInSphere, __iEnt, __fOrigin, MAX_DISTANCE)) != 0)
{
if (is_nullent(__iEnt) || !FClassnameIs(__iEnt, __BODY_CLASSNAME) || IsReviving(__iEnt)) continue;
__iPlayer = get_entvar(__iEnt, var_iuser1);
if (!__IsValidTeam(__iPlayer)) continue;
#if defined MAX_USER
if (__g_PlayersData[__iPlayer][__g_ReviveMax] >= MAX_USER) continue;
#endif
#if defined ENEMY_MODE
if (get_member(__id, m_iTeam) != get_member(__iPlayer, m_iTeam))
{
if (__g_PlayersData[__iPlayer][__g_IsBoomPlayer]) continue;
client_print(__id, print_center, "Вы минируете %n..", __iPlayer);
} else client_print(__id, print_center, "Вы воскрешаете %n..", __iPlayer);
#else
client_print(__id, print_center, "Вы воскрешаете %n..", __iPlayer);
#endif
StartRevive(__iEnt);
__g_PlayersData[__id][__g_iPlayerIndexEntity] = __iEnt;
#if defined BAR
rg_send_bartime(__id, TIME);
#endif
#if defined SPEED
rg_reset_maxspeed(__id);
#endif
remove_task(__id + __TASK_REVIVE); set_task(TIME.0, "__respawn_friendly", __id + __TASK_REVIVE);
RequestFrame("__CBasePlayer_PreThink", __id);
break;
}
}
__stop_revive(__id)
{
if (!__g_PlayersData[__id][__g_iPlayerIndexEntity]) return;
StopRevive(__g_PlayersData[__id][__g_iPlayerIndexEntity]);
__g_PlayersData[__id][__g_iPlayerIndexEntity] = 0;
__g_PlayersData[__id][__g_fDelay] = get_gametime() + FLOOD;
#if defined SPEED
rg_reset_maxspeed(__id);
#endif
#if defined BAR
rg_send_bartime(__id, 0);
#endif
remove_task(__id + __TASK_REVIVE);
}
public __CBasePlayer_PreThink(__id)
{
if (!is_user_alive(__id)) __stop_revive(__id);
else
{
if ( !__g_PlayersData[__id][__g_iPlayerIndexEntity]) return;
new Float:__fOrigin[3], Float:__fOrigin2[3];
get_entvar(__id, var_origin, __fOrigin);
get_entvar(__g_PlayersData[__id][__g_iPlayerIndexEntity], var_origin, __fOrigin2);
if (vector_distance(__fOrigin, __fOrigin2) > MAX_DISTANCE)
{
__stop_revive(__id);
client_print_color(__id, print_team_red, "%s ^3не уходите далеко от трупа", __g_bPrefix);
} else RequestFrame("__CBasePlayer_PreThink", __id);
}
}
#if defined SPEED
public __CBasePlayer_ResetMaxSpeed_Post(const __this) if (__g_PlayersData[__this][__g_iPlayerIndexEntity]) set_entvar(__this, var_maxspeed, 175.0);
#endif
public __respawn_friendly(__taskid)
{
new __id = __ID_REVIVE;
new __iEnt = __g_PlayersData[__id][__g_iPlayerIndexEntity];
if (is_nullent(__iEnt)) return;
new __player = get_entvar(__iEnt, var_iuser1);
if (!is_user_connected(__player) || get_member_game(m_bRoundTerminating) ) return;
__stop_revive(__id);
if (get_member(__player, m_iTeam) == get_member(__id, m_iTeam))
{
#if defined ENEMY_MODE
if (__g_PlayersData[__player][__g_IsBoomPlayer])
{
#if defined KILL_EFFECT
new Float:__fPlayerOrigin[3]; get_entvar(__id, var_origin, __fPlayerOrigin);
message_begin_f(MSG_PVS, SVC_TEMPENTITY, __fPlayerOrigin);
{
write_byte(TE_LAVASPLASH);
write_coord_f(__fPlayerOrigin[0]); // position.x
write_coord_f(__fPlayerOrigin[1]); // position.y
write_coord_f(__fPlayerOrigin[2]); // position.z
}
message_end();
#endif
client_print_color(__id, print_team_red, "%s ^3%n заминирован", __g_bPrefix, __player);
ExecuteHamB(Ham_Killed, __id, __g_PlayersData[__player][__g_IsBoomPlayer], GIB_ALWAYS); return;
}
#endif
rg_round_respawn(__player);
#if defined SPAWN
new Float:__fOrigin[3]; get_entvar(__iEnt, var_origin, __fOrigin);
engfunc(EngFunc_SetOrigin, __player, __fOrigin);
set_entvar(__player, var_flags, get_entvar(__player, var_flags) | FL_DUCKING);
set_entvar(__player, var_view_ofs, Float:{0.0, 0.0, 12.0});
#endif
#if defined NEW_HP
set_entvar(__player, var_health, NEW_HP);
#endif
#if defined NOTIFY
client_print_color(0, __id, "%s ^3%n ^1воскресил^3 %n", __g_bPrefix, __id, __player);
#endif
#if defined SOUNDS
rh_emit_sound2(__player, 0, CHAN_BODY, __g_bSoundRevive);
#endif
#if defined MAX_USER
__g_PlayersData[__player][__g_ReviveMax]++;
#endif
#if defined API
ExecuteForward(__gForwards[__Fw_Revived], __gForwards[__Fw_Return], __player, __id);
#endif
set_entvar(__iEnt, var_flags, FL_KILLME);
}
#if defined ENEMY_MODE
else
{
__g_PlayersData[__player][__g_IsBoomPlayer] = __id;
client_print_color(__id, print_team_blue, "%s ^3вы успешно заминировали ^4%n", __g_bPrefix, __player);
#if defined SOUNDS
rh_emit_sound2(__player, 0, CHAN_BODY, __g_bSoundMining);
#endif
#if defined API
ExecuteForward(__gForwards[__Fw_Mined], __gForwards[__Fw_Return], __player, __id);
#endif
}
#endif
#if defined COST
rg_add_account(__id, -COST);
#endif
#if defined MAX
__g_PlayersData[__id][__g_ReviveCount]++;
#endif
}
public __MsgHookClCorpse()
{
new __player = get_msg_arg_int(12);
new __iEnt = rg_create_entity("info_target");
if (is_nullent(__iEnt)) return PLUGIN_CONTINUE;
new __model[32]; get_msg_arg_string(1, __model, charsmax(__model));
new Float:__origin[3], Float:__angles[3]; get_entvar(__player, var_origin, __origin); get_entvar(__player, var_angles, __angles);
engfunc(EngFunc_SetModel, __iEnt, fmt("models/player/%s/%s.mdl", __model, __model));
engfunc(EngFunc_SetOrigin, __iEnt, __origin);
set_entvar(__iEnt, var_classname, __BODY_CLASSNAME);
set_entvar(__iEnt, var_angles, __angles);
set_entvar(__iEnt, var_body, get_entvar(__player, var_body));
set_entvar(__iEnt, var_skin, get_entvar(__player, var_skin));
set_entvar(__iEnt, var_framerate, 1.0);
set_entvar(__iEnt, var_sequence, get_entvar(__player, var_sequence));
set_entvar(__iEnt, var_gaitsequence, get_entvar(__player, var_gaitsequence));
set_entvar(__iEnt, var_iuser1, __player);
StopRevive(__iEnt);
return PLUGIN_HANDLED;
}