/**
История изменений:
0.1b (23.07.2023) by b0t.
- Первый релиз;
*/
new const VERSION[] = "0.1b";
#include <amxmodx>
#include <reapi>
#pragma semicolon 1
#define AUTO_CONFIG //Автоматическое создание .cfg файла с настройками;
enum _:CvarsData {
FLAG_ACCESS,
CMD_MEDIC[128],
MAX_HP_UP_IN_ROUND,
MAX_HP_SHOT_IN_ROUND,
HP_UP,
PRINT_MESSAGE
};
enum _:UseMedicData {
YOURSELF,
Float:ALLY
};
new
gCvars[CvarsData],
pUseMedic[33][UseMedicData],
g_pCvarFlagAccess,
g_szFlagAccess[64];
public plugin_init() {
register_plugin("Medic",VERSION,"b0t.");
RegisterHookChain(RG_CBasePlayer_TraceAttack,"CBasePlayer_TraceAttack_Post", .post = true);
RegisterHookChain(RG_CSGameRules_OnRoundFreezeEnd,"CSGameRules_OnRoundFreezeEnd_Post", .post = true);
CreateCvars();
UTIL__RegisterClCmd(gCvars[CMD_MEDIC],"Func__Medic");
hook_cvar_change(g_pCvarFlagAccess,"Hook_CvarChange");
#if defined AUTO_CONFIG
AutoExecConfig(.name = "Medic");
#endif
}
public CBasePlayer_TraceAttack_Post(const pVictim,const pAttacker,const Float:fDamage,const Float:fVecDir[3],const iTrace,const iDmgType) {
if(!is_user_connected(pAttacker) || !is_user_connected(pVictim))
return HC_CONTINUE;
if(~get_user_flags(pAttacker) & gCvars[FLAG_ACCESS])
return HC_CONTINUE;
if(iDmgType & DMG_GRENADE)
return HC_CONTINUE;
new iActiveItem = get_member(pAttacker,m_pActiveItem);
if(get_member(iActiveItem,m_iId) == WEAPON_KNIFE)
return HC_CONTINUE;
if(get_member(pAttacker,m_iTeam) == get_member(pVictim,m_iTeam)) {
if(pUseMedic[pAttacker][ALLY] <= 0.0)
return HC_CONTINUE;
new Float:fHp = Float:get_entvar(pVictim,var_health);
new Float:fAddHp = floatclamp(fHp+float(gCvars[HP_UP]),1.0,100.0);
new Float:fDifference = fAddHp-fHp;
if(!fDifference)
return HC_CONTINUE;
if(fDifference > pUseMedic[pAttacker][ALLY]) {
fAddHp = floatclamp(fHp+pUseMedic[pAttacker][ALLY],1.0,100.0);
fDifference = fAddHp-fHp;
}
set_entvar(pVictim,var_health,fAddHp);
pUseMedic[pAttacker][ALLY] -= fDifference;
if(gCvars[PRINT_MESSAGE])
client_print(pAttacker,print_center,"[%.0f/%i]",pUseMedic[pAttacker][ALLY],gCvars[MAX_HP_SHOT_IN_ROUND]);
}
return HC_CONTINUE;
}
public CSGameRules_OnRoundFreezeEnd_Post() {
for(new id=1;id<=MaxClients;id++) {
if(!is_user_connected(id) || is_user_bot(id) || is_user_hltv(id))
continue;
if(~get_user_flags(id) & gCvars[FLAG_ACCESS])
continue;
pUseMedic[id][YOURSELF] = gCvars[MAX_HP_UP_IN_ROUND];
pUseMedic[id][ALLY] = float(gCvars[MAX_HP_SHOT_IN_ROUND]);
}
}
public Func__Medic(const id) {
if(pUseMedic[id][YOURSELF] <= 0)
return PLUGIN_HANDLED;
set_entvar(id,var_health,100.0);
pUseMedic[id][YOURSELF]--;
return PLUGIN_HANDLED;
}
public CreateCvars() {
bind_pcvar_string(
g_pCvarFlagAccess = create_cvar(
.name = "medic_flag_access",
.string = "n",
.description = "Флаг доступа к возможностям 'медика'"
),
g_szFlagAccess,charsmax(g_szFlagAccess)
);
gCvars[FLAG_ACCESS] = read_flags(g_szFlagAccess);
bind_pcvar_string(
create_cvar(
.name = "medic_clcmd",
.string = "medic",
.description = "Команда для пополнения хп (все чаты + консоль)"
),
gCvars[CMD_MEDIC],charsmax(gCvars[CMD_MEDIC])
);
bind_pcvar_num(
create_cvar(
.name = "medic_max_hp_up_in_round",
.string = "2",
.description = "Сколько раз 'медик' может вылечить себя"
),
gCvars[MAX_HP_UP_IN_ROUND]
);
bind_pcvar_num(
create_cvar(
.name = "medic_max_hp_shot_in_round",
.string = "500",
.description = "Сколько HP 'медик' может пополнить союзникам"
),
gCvars[MAX_HP_SHOT_IN_ROUND]
);
bind_pcvar_num(
create_cvar(
.name = "medic_hp_up",
.string = "10",
.description = "Сколько HP 'медик' может пополнить союзнику за выстрел"
),
gCvars[HP_UP]
);
bind_pcvar_num(
create_cvar(
.name = "medic_print_message",
.string = "1",
.description = "Отображать лимит пополнения хп для союзников"
),
gCvars[PRINT_MESSAGE]
);
}
public Hook_CvarChange(const pCvar,const szOldValue[],const szNewValue[]) {
new iFlagsOld = read_flags(szOldValue);
new iFlagsNew = read_flags(szNewValue);
if(iFlagsOld != iFlagsNew)
gCvars[FLAG_ACCESS] = iFlagsNew;
}
public client_putinserver(id) {
pUseMedic[id][YOURSELF] = 0;
pUseMedic[id][ALLY] = 0.0;
}
/**
* Зарегистрирует команду во всех чатах + консоль
*
* @param szCmd Команда
* @param szFunc Функция обработчик
*
* @return -
*/
stock UTIL__RegisterClCmd(const szCmd[],const szFunc[]) {
register_clcmd(fmt("%s",szCmd),szFunc);
register_clcmd(fmt("say /%s",szCmd),szFunc);
register_clcmd(fmt("say_team /%s",szCmd),szFunc);
}