#include <amxmodx>
#include <hamsandwich>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Bonus";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_bonus.cfg";
#define MAX_SPAWN_WEAPONS 6
enum CVARS {
WEAPONS[MAX_FMT_LENGTH],
WEAPONS_MAPS[MAX_FMT_LENGTH],
Float:REVIVE_HEALTH,
Float:PLANTING_HEALTH,
Float:HEALTH,
ARMOR_TYPE,
ARMOR,
FRAGS,
NO_DEATHPOINT
};
new g_eCvars[CVARS];
new g_iWeapons;
new g_szWeapon[MAX_SPAWN_WEAPONS][32];
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
}
public plugin_cfg() {
new szMapName[MAX_MAPNAME_LENGTH], szWeapon[32];
get_mapname(szMapName, charsmax(szMapName));
if(g_eCvars[WEAPONS_MAPS][0] != EOS && containi(szMapName, "awp_") != -1) {
while(argbreak(g_eCvars[WEAPONS_MAPS], szWeapon, charsmax(szWeapon), g_eCvars[WEAPONS_MAPS], charsmax(g_eCvars[WEAPONS_MAPS])) != -1) {
if(g_iWeapons == MAX_SPAWN_WEAPONS)
break;
copy(g_szWeapon[g_iWeapons++], charsmax(g_szWeapon[]), szWeapon);
}
return;
}
if(g_eCvars[WEAPONS][0] != EOS) {
while(argbreak(g_eCvars[WEAPONS], szWeapon, charsmax(szWeapon), g_eCvars[WEAPONS], charsmax(g_eCvars[WEAPONS])) != -1) {
if(g_iWeapons == MAX_SPAWN_WEAPONS)
break;
copy(g_szWeapon[g_iWeapons++], charsmax(g_szWeapon[]), szWeapon);
}
}
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(eMode) {
case MODE_REVIVE: {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(iMode != MODE_PLANT) {
if(g_eCvars[REVIVE_HEALTH])
rg_add_health_to_player(iActivator, g_eCvars[REVIVE_HEALTH]);
if(g_eCvars[HEALTH])
set_entvar(iPlayer, var_health, floatclamp(g_eCvars[HEALTH], 1.0, Float:get_entvar(iPlayer, var_max_health)));
if(g_eCvars[ARMOR])
rg_set_user_armor(iPlayer, g_eCvars[ARMOR], ArmorType:g_eCvars[ARMOR_TYPE]);
if(g_iWeapons > 0) {
rg_remove_all_items(iPlayer);
for(new i; i <= g_iWeapons; i++) {
new iWeapon = rg_give_item(iPlayer, g_szWeapon[i]);
if(!is_nullent(iWeapon)) {
new WeaponIdType:iWeaponType = WeaponIdType:get_member(iWeapon, m_iId);
if(iWeaponType != WEAPON_KNIFE && iWeaponType != WEAPON_SHIELDGUN)
rg_set_user_bpammo(iPlayer, iWeaponType, rg_get_iteminfo(iWeapon, ItemInfo_iMaxAmmo1));
}
}
}
if(g_eCvars[FRAGS])
ExecuteHamB(Ham_AddPoints, iActivator, g_eCvars[FRAGS], false);
if(g_eCvars[NO_DEATHPOINT])
set_member(iPlayer, m_iDeaths, max(get_member(iPlayer, m_iDeaths) - 1, 0));
}
}
case MODE_PLANT: {
if(g_eCvars[PLANTING_HEALTH])
rg_add_health_to_player(iActivator, g_eCvars[PLANTING_HEALTH]);
}
}
}
stock rg_add_health_to_player(const iPlayer, const Float:flHealth) {
set_entvar(iPlayer, var_health, floatclamp(Float:get_entvar(iPlayer, var_health) + flHealth, 1.0, Float:get_entvar(iPlayer, var_max_health)));
}
public CreateCvars() {
bind_pcvar_string(create_cvar(
"rt_weapons",
"weapon_knife weapon_deagle",
FCVAR_NONE,
"What weapons should be given to the player after resurrection(no more than 6)(otherwise standard from game.cfg)"),
g_eCvars[WEAPONS],
charsmax(g_eCvars[WEAPONS])
);
bind_pcvar_string(create_cvar(
"rt_weapons_maps",
"weapon_knife weapon_awp",
FCVAR_NONE,
"What weapons should be given to the player after resurrection on 'awp_' maps(no more than 6)(otherwise standard from game.cfg)"),
g_eCvars[WEAPONS_MAPS],
charsmax(g_eCvars[WEAPONS_MAPS])
);
bind_pcvar_float(create_cvar(
"rt_revive_health",
"0.0",
FCVAR_NONE,
"How much more health to add after resurrection",
true,
0.0),
g_eCvars[REVIVE_HEALTH]
);
bind_pcvar_float(create_cvar(
"rt_planting_health",
"0.0",
FCVAR_NONE,
"How much more health to add after planting",
true,
0.0),
g_eCvars[PLANTING_HEALTH]
);
bind_pcvar_float(create_cvar(
"rt_health",
"100.0",
FCVAR_NONE,
"The number of health of the resurrected player",
true,
1.0),
g_eCvars[HEALTH]
);
bind_pcvar_num(create_cvar(
"rt_armor_type",
"2",
FCVAR_NONE,
"0 - do not issue armor, 1 - bulletproof vest, 2 - bulletproof vest with helmet",
true,
0.0,
true,
2.0),
g_eCvars[ARMOR_TYPE]
);
bind_pcvar_num(create_cvar(
"rt_armor",
"100",
FCVAR_NONE,
"Number of armor of the resurrected player",
true,
0.0),
g_eCvars[ARMOR]
);
bind_pcvar_num(create_cvar(
"rt_frags",
"1",
FCVAR_NONE,
"Number of frags for resurrection",
true,
0.0),
g_eCvars[FRAGS]
);
bind_pcvar_num(create_cvar(
"rt_restore_death",
"0",
FCVAR_NONE,
"Remove the death point of a dead player after resurrection",
true,
0.0,
true,
1.0),
g_eCvars[NO_DEATHPOINT]
);
}
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Core";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_core.cfg";
// Custom Player Models https://dev-cs.ru/resources/928/
native bool:custom_player_models_get_path(const player, path[] = "", length = 0);
native bool:custom_player_models_get_body(const player, const any:team, &body);
native bool:custom_player_models_get_skin(const player, const any:team, &skin);
enum CVARS {
Float:REVIVE_TIME,
Float:ANTIFLOOD_TIME,
Float:CORPSE_TIME,
Float:SEARCH_RADIUS,
FORCE_FWD_MODE
};
new g_eCvars[CVARS];
enum Forwards {
ReviveStart,
ReviveStart_Post,
ReviveLoop_Pre,
ReviveLoop_Post,
ReviveEnd,
ReviveCancelled,
CreatingCorpseStart,
CreatingCorpseEnd
};
new g_eForwards[Forwards];
new g_iPlantingPluginID;
new Float:g_fLastUse[MAX_PLAYERS + 1], g_iTimeUntil[MAX_PLAYERS + 1];
new Float:g_fVecSpawnOrigin[3];
new HookChain:g_pHook_GetPlayerSpawnSpot;
new g_szModel[MAX_PLAYERS + 1][64];
new Modes:g_iCurrentMode[MAX_PLAYERS + 1] = { MODE_NONE, ... };
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
register_message(get_user_msgid("ClCorpse"), "MessageHook_ClCorpse");
RegisterHookChain(RG_CSGameRules_CleanUpMap, "CSGameRules_CleanUpMap_Post", true);
RegisterHookChain(RG_CBasePlayer_UseEmpty, "CBasePlayer_UseEmpty_Pre", false);
DisableHookChain((g_pHook_GetPlayerSpawnSpot = RegisterHookChain(RG_CSGameRules_GetPlayerSpawnSpot, "CSGameRules_GetPlayerSpawnSpot_Pre", false)));
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn_Pre", false);
RegisterHookChain(RG_CBasePlayer_SetClientUserInfoModel, "CBasePlayer_SetClientUserInfoModel_Pre");
g_eForwards[ReviveStart] = CreateMultiForward("rt_revive_start", ET_STOP, FP_CELL, FP_CELL, FP_CELL, FP_CELL);
g_eForwards[ReviveStart_Post] = CreateMultiForward("rt_revive_start_post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL);
g_eForwards[ReviveLoop_Pre] = CreateMultiForward("rt_revive_loop_pre", ET_STOP, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL);
g_eForwards[ReviveLoop_Post] = CreateMultiForward("rt_revive_loop_post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL);
g_eForwards[ReviveEnd] = CreateMultiForward("rt_revive_end", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL);
g_eForwards[ReviveCancelled] = CreateMultiForward("rt_revive_cancelled", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL);
g_eForwards[CreatingCorpseStart] = CreateMultiForward("rt_creating_corpse_start", ET_STOP, FP_CELL, FP_CELL);
g_eForwards[CreatingCorpseEnd] = CreateMultiForward("rt_creating_corpse_end", ET_IGNORE, FP_CELL, FP_CELL, FP_ARRAY);
g_iPlantingPluginID = is_plugin_loaded("rt_planting.amxx", true);
}
public client_disconnected(iPlayer) {
g_fLastUse[iPlayer] = 0.0;
PlayerSpawnOrDisconnect(iPlayer);
}
public client_remove(iPlayer) {
g_iCurrentMode[iPlayer] = MODE_NONE;
}
public CSGameRules_CleanUpMap_Post() {
arrayset(g_iCurrentMode, MODE_NONE, sizeof(g_iCurrentMode));
RemoveCorpses(0, DEAD_BODY_CLASSNAME);
}
public CBasePlayer_UseEmpty_Pre(const iActivator) {
if(~get_entvar(iActivator, var_flags) & FL_ONGROUND)
return;
new iEnt = RT_NULLENT;
new Float:fVecPlOrigin[3], Float:fVecEntOrigin[3];
get_entvar(iActivator, var_origin, fVecPlOrigin);
while((iEnt = rg_find_ent_by_class(iEnt, DEAD_BODY_CLASSNAME)) > 0) {
if(!is_nullent(iEnt)) {
get_entvar(iEnt, var_vuser4, fVecEntOrigin);
if(ExecuteHam(Ham_FVecInViewCone, iActivator, fVecEntOrigin) && vector_distance(fVecPlOrigin, fVecEntOrigin) < g_eCvars[SEARCH_RADIUS]) {
Corpse_Use(iEnt, iActivator);
return;
}
}
}
}
public CSGameRules_GetPlayerSpawnSpot_Pre(const iPlayer) {
DisableHookChain(g_pHook_GetPlayerSpawnSpot);
set_entvar(iPlayer, var_flags, get_entvar(iPlayer, var_flags) | FL_DUCKING);
set_entvar(iPlayer, var_velocity, NULL_VECTOR);
set_entvar(iPlayer, var_v_angle, NULL_VECTOR);
new Float:fVecAngles[3];
get_entvar(iPlayer, var_angles, fVecAngles);
fVecAngles[0] = fVecAngles[2] = 0.0;
set_entvar(iPlayer, var_angles, fVecAngles);
set_entvar(iPlayer, var_punchangle, NULL_VECTOR);
set_entvar(iPlayer, var_fixangle, 1);
engfunc(EngFunc_SetSize, iPlayer, Float:{-16.000000, -16.000000, -18.000000}, Float:{16.000000, 16.000000, 32.000000});
engfunc(EngFunc_SetOrigin, iPlayer, g_fVecSpawnOrigin);
SetHookChainReturn(ATYPE_INTEGER, RT_NULLENT);
return HC_SUPERCEDE;
}
public CBasePlayer_Spawn_Pre(const iPlayer) {
PlayerSpawnOrDisconnect(iPlayer);
}
public CBasePlayer_SetClientUserInfoModel_Pre(const iPlayer, szInfoBuffer[], szNewModel[]) {
copy(g_szModel[iPlayer], charsmax(g_szModel[]), szNewModel);
}
public Corpse_Use(const iEnt, const iActivator) {
if(is_nullent(iEnt) || get_member_game(m_bRoundTerminating) || !ExecuteHam(Ham_IsPlayer, iActivator))
return;
new iPlayer = get_entvar(iEnt, var_owner);
new TeamName:iPlTeam = TeamName:get_member(iPlayer, m_iTeam);
new TeamName:iActTeam = TeamName:get_member(iActivator, m_iTeam);
new TeamName:iEntTeam = TeamName:get_entvar(iEnt, var_team);
new Modes:eCurrentMode = (iActTeam == iPlTeam) ? MODE_REVIVE : MODE_PLANT;
if(g_iPlantingPluginID == INVALID_PLUGIN_ID && eCurrentMode == MODE_PLANT)
return;
if(iActTeam == TEAM_SPECTATOR || iPlTeam == TEAM_SPECTATOR)
return;
if(iEntTeam != iPlTeam) {
NotifyClient(iActivator, print_team_red, "RT_CHANGE_TEAM");
return;
}
if(get_entvar(iEnt, var_iuser1)) {
NotifyClient(iActivator, print_team_red, "RT_ACTIVATOR_EXISTS");
return;
}
if(!is_user_alive(iActivator)) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
new fwRet;
ExecuteForward(g_eForwards[ReviveStart], fwRet, iEnt, iPlayer, iActivator, eCurrentMode);
if(fwRet == PLUGIN_HANDLED) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
new Float:fGameTime = get_gametime();
if(g_fLastUse[iActivator] > fGameTime) {
NotifyClient(iActivator, print_team_red, "RT_ANTI_FLOOD");
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
g_fLastUse[iActivator] = fGameTime + g_eCvars[ANTIFLOOD_TIME];
NotifyClient(iActivator, print_team_blue, eCurrentMode == MODE_REVIVE ? "RT_TIMER_REVIVE" : "RT_TIMER_PLANT", iPlayer);
g_iTimeUntil[iActivator] = 0;
set_entvar(iEnt, var_iuser1, iActivator);
set_entvar(iEnt, var_iuser2, eCurrentMode);
set_entvar(iEnt, var_fuser1, fGameTime + g_eCvars[REVIVE_TIME]);
set_entvar(iEnt, var_fuser3, g_eCvars[REVIVE_TIME]);
set_entvar(iEnt, var_nextthink, fGameTime + 0.1);
g_iCurrentMode[iActivator] = eCurrentMode;
ExecuteForward(g_eForwards[ReviveStart_Post], _, iEnt, iPlayer, iActivator, eCurrentMode);
}
public Corpse_Think(const iEnt) {
if(is_nullent(iEnt))
return;
new iPlayer = get_entvar(iEnt, var_owner);
new iActivator = get_entvar(iEnt, var_iuser1);
new Float:fGameTime = get_gametime();
if(!iActivator) {
if(g_eCvars[CORPSE_TIME] && Float:get_entvar(iEnt, var_fuser4) < fGameTime) {
RemoveCorpses(iPlayer, DEAD_BODY_CLASSNAME);
return;
}
set_entvar(iEnt, var_nextthink, fGameTime + 1.0);
return;
}
new TeamName:iPlTeam = TeamName:get_member(iPlayer, m_iTeam);
new TeamName:iEntTeam = TeamName:get_entvar(iEnt, var_team);
new Modes:eCurrentMode = Modes:get_entvar(iEnt, var_iuser2);
if(iEntTeam != iPlTeam) {
NotifyClient(iActivator, print_team_red, "RT_CHANGE_TEAM");
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
if(~get_entvar(iActivator, var_button) & IN_USE) {
NotifyClient(iActivator, print_team_red, eCurrentMode == MODE_REVIVE ? "RT_CANCELLED_REVIVE" : "RT_CANCELLED_PLANT");
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
new Float:fTimeUntil[2];
fTimeUntil[0] = Float:get_entvar(iEnt, var_fuser1);
fTimeUntil[1] = Float:get_entvar(iEnt, var_fuser3);
g_iTimeUntil[iActivator]++;
if(g_iTimeUntil[iActivator] == 10 || g_eCvars[FORCE_FWD_MODE]) {
if(g_eCvars[FORCE_FWD_MODE]) {
fTimeUntil[1] -= 0.1;
}
else {
fTimeUntil[1] -= 1.0;
}
if(!is_user_alive(iActivator)) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
new fwRet;
ExecuteForward(g_eForwards[ReviveLoop_Pre], fwRet, iEnt, iPlayer, iActivator, fTimeUntil[1], eCurrentMode);
if(fwRet == PLUGIN_HANDLED) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
}
if(fGameTime > fTimeUntil[0]) {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(eCurrentMode == MODE_REVIVE && iMode != MODE_PLANT) {
NotifyClient(iActivator, print_team_red, "RT_REVIVE", iPlayer);
NotifyClient(iPlayer, print_team_red, "RT_REVIVED", iActivator);
get_entvar(iActivator, var_origin, g_fVecSpawnOrigin);
RemoveCorpses(iPlayer, DEAD_BODY_CLASSNAME);
EnableHookChain(g_pHook_GetPlayerSpawnSpot);
rg_round_respawn(iPlayer);
DisableHookChain(g_pHook_GetPlayerSpawnSpot);
if(is_user_alive(iPlayer))
engfunc(EngFunc_SetOrigin, iPlayer, g_fVecSpawnOrigin);
}
if(!is_user_alive(iActivator)) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
g_iCurrentMode[iActivator] = MODE_NONE;
ExecuteForward(g_eForwards[ReviveEnd], _, iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
if(g_iTimeUntil[iActivator] == 10 || g_eCvars[FORCE_FWD_MODE]) {
if(!is_user_alive(iActivator)) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, iPlayer, iActivator, eCurrentMode);
return;
}
ExecuteForward(g_eForwards[ReviveLoop_Post], _, iEnt, iPlayer, iActivator, fTimeUntil[1], eCurrentMode);
g_iTimeUntil[iActivator] = 0;
}
set_entvar(iEnt, var_fuser3, fTimeUntil[1]);
set_entvar(iEnt, var_nextthink, fGameTime + 0.1);
}
public MessageHook_ClCorpse() {
if(get_member_game(m_bRoundTerminating))
return PLUGIN_HANDLED;
enum {
arg_body = 10,
arg_id = 12
};
new iPlayer = get_msg_arg_int(arg_id);
new TeamName:iPlTeam = TeamName:get_member(iPlayer, m_iTeam);
if(iPlTeam == TEAM_SPECTATOR || g_szModel[iPlayer][0] == EOS)
return PLUGIN_HANDLED;
new iEnt = rg_create_entity("info_target");
new fwRet;
ExecuteForward(g_eForwards[CreatingCorpseStart], fwRet, iEnt, iPlayer);
if(fwRet == PLUGIN_HANDLED) {
set_entvar(iEnt, var_flags, FL_KILLME);
set_entvar(iEnt, var_nextthink, 0.0);
return PLUGIN_HANDLED;
}
/*new szModel[32], szModelPath[MAX_RESOURCE_PATH_LENGTH];
get_user_info(iPlayer, "model", szModel, charsmax(szModel));
formatex(szModelPath, charsmax(szModelPath), "models/player/%s/%s.mdl", szModel, szModel);*/
new szModelPath[MAX_RESOURCE_PATH_LENGTH];
if(!custom_player_models_get_path(iPlayer, szModelPath, charsmax(szModelPath))) {
formatex(szModelPath, charsmax(szModelPath), "models/player/%s/%s.mdl", g_szModel[iPlayer], g_szModel[iPlayer]);
set_entvar(iEnt, var_body, get_msg_arg_int(arg_body));
set_entvar(iEnt, var_skin, get_entvar(iPlayer, var_skin));
}
else {
new iBody, iSkin;
custom_player_models_get_body(iPlayer, iPlTeam, iBody);
custom_player_models_get_skin(iPlayer, iPlTeam, iSkin);
set_entvar(iEnt, var_body, iBody);
set_entvar(iEnt, var_skin, iSkin);
}
set_entvar(iEnt, var_modelindex, engfunc(EngFunc_ModelIndex, szModelPath));
set_entvar(iEnt, var_model, szModelPath);
//set_entvar(iEnt, var_renderfx, kRenderFxDeadPlayer);
//set_entvar(iEnt, var_renderamt, float(iPlayer));
set_entvar(iEnt, var_classname, DEAD_BODY_CLASSNAME);
set_entvar(iEnt, var_sequence, get_entvar(iPlayer, var_sequence));
set_entvar(iEnt, var_frame, 255.0);
set_entvar(iEnt, var_owner, iPlayer);
set_entvar(iEnt, var_team, iPlTeam);
new Float:fVecOrigin[3];
fVecOrigin[0] = float(get_msg_arg_int(2) / 128);
fVecOrigin[1] = float(get_msg_arg_int(3) / 128);
fVecOrigin[2] = float(get_msg_arg_int(4) / 128);
//get_entvar(iPlayer, var_origin, fVecOrigin);
engfunc(EngFunc_SetOrigin, iEnt, fVecOrigin);
new Float:fVecAngles[3];
get_entvar(iPlayer, var_angles, fVecAngles);
set_entvar(iEnt, var_angles, fVecAngles);
engfunc(EngFunc_GetBonePosition, iEnt, 2, fVecOrigin, fVecAngles);
set_entvar(iEnt, var_vuser4, fVecOrigin);
set_entvar(iEnt, var_fuser2, g_eCvars[SEARCH_RADIUS]);
set_entvar(iEnt, var_nextthink, get_gametime() + 1.0);
SetThink(iEnt, "Corpse_Think");
if(g_eCvars[CORPSE_TIME])
set_entvar(iEnt, var_fuser4, get_gametime() + g_eCvars[CORPSE_TIME]);
fVecOrigin[2] += 20.0;
ExecuteForward(g_eForwards[CreatingCorpseEnd], _, iEnt, iPlayer, PrepareArray(_:fVecOrigin, sizeof(fVecOrigin)));
return PLUGIN_HANDLED;
}
stock PlayerSpawnOrDisconnect(const iPlayer) {
new iActivator = RemoveCorpses(iPlayer, DEAD_BODY_CLASSNAME);
if(is_user_connected(iActivator))
NotifyClient(iActivator, print_team_red, "RT_DISCONNECTED");
ResetCorpseThink(g_eForwards[ReviveCancelled], RT_NULLENT, iPlayer, iActivator, MODE_NONE);
// TODO need to handle corpse user respawn
//if(g_iCurrentMode[iPlayer]) { }
}
public CreateCvars() {
bind_pcvar_float(create_cvar(
"rt_revive_time",
"3.0",
FCVAR_NONE,
"Duration of the player's resurrection(in seconds)",
true,
1.0),
g_eCvars[REVIVE_TIME]
);
bind_pcvar_float(create_cvar(
"rt_revive_antiflood",
"3.0",
FCVAR_NONE,
"Duration of anti-flood resurrection(in seconds)",
true,
1.0),
g_eCvars[ANTIFLOOD_TIME]
);
bind_pcvar_float(create_cvar(
"rt_corpse_time",
"30.0",
FCVAR_NONE,
"Duration of a corpse's life (in seconds). If you set it to 0, the corpse lives until the end of the round.",
true,
0.0),
g_eCvars[CORPSE_TIME]
);
bind_pcvar_float(create_cvar(
"rt_search_radius",
"64.0",
FCVAR_NONE,
"Search radius for a corpse",
true,
1.0),
g_eCvars[SEARCH_RADIUS]
);
bind_pcvar_num(create_cvar(
"rt_force_fwd_mode",
"0",
FCVAR_NONE,
"Execute forwards more often. Set this to 1 if 'rt_no_move 1' didn't work properly.",
true,
0.0,
true,
1.0),
g_eCvars[FORCE_FWD_MODE]
);
}
/**
* Reset entity think
*
* @param eForward Forward type
* @param iEnt Corpse entity index
* @param iPlayer Player id whose corpse
* @param iActivator Player id who ressurect
* @param eMode MODE_REVIVE - stopped the resurrection, MODE_PLANT - stopped planting
*
* @noreturn
*/
ResetCorpseThink(const eForward, const iEnt, iPlayer, iActivator, const Modes:eMode) {
if(!is_nullent(iEnt)) {
set_entvar(iEnt, var_nextthink, get_gametime() + 1.0);
set_entvar(iEnt, var_iuser1, 0);
}
if(iActivator != RT_NULLENT) {
g_iCurrentMode[iActivator] = MODE_NONE;
}
iPlayer = is_user_connected(iPlayer) ? iPlayer : RT_NULLENT;
iActivator = is_user_connected(iActivator) ? iActivator : RT_NULLENT;
ExecuteForward(eForward, _, iEnt, iPlayer, iActivator, eMode);
}
public plugin_natives() {
set_native_filter("native_filter");
register_native("rt_get_user_mode", "_rt_get_user_mode");
register_native("rt_reset_use", "_rt_reset_use");
}
public Modes:_rt_get_user_mode() {
enum { arg_user = 1 };
return g_iCurrentMode[ get_param(arg_user) ];
}
public bool:_rt_reset_use() {
enum { arg_user = 1 };
new pPlayer = get_param(arg_user);
if(g_iCurrentMode[pPlayer] == MODE_NONE) {
return false;
}
new iEnt = RT_NULLENT;
while((iEnt = rg_find_ent_by_class(iEnt, DEAD_BODY_CLASSNAME)) > 0) {
if(!is_entity(iEnt)) {
continue;
}
if(pPlayer == get_entvar(iEnt, var_iuser1)) {
ResetCorpseThink(g_eForwards[ReviveCancelled], iEnt, get_entvar(iEnt, var_owner), pPlayer, get_entvar(iEnt, var_iuser2));
return true;
}
}
g_iCurrentMode[pPlayer] = MODE_NONE;
return false;
}
public native_filter(const szNativeName[], iNativeID, iTrapMode) {
return PLUGIN_HANDLED;
}
#include <amxmodx>
#include <fakemeta>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Effects";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_effects.cfg";
new const CORPSE_SPRITE_CLASSNAME[] = "rt_corpse_sprite";
enum CVARS {
SPECTATOR,
NOTIFY_DHUD,
REVIVE_COLORS[MAX_COLORS_LENGTH],
REVIVE_COORDS[MAX_COORDS_LENGTH],
PLANTING_COLORS[MAX_COLORS_LENGTH],
PLANTING_COORDS[MAX_COORDS_LENGTH],
CORPSE_SPRITE[MAX_RESOURCE_PATH_LENGTH],
Float:SPRITE_SCALE,
REVIVE_GLOW[32],
PLANTING_GLOW[32]
};
new g_eCvars[CVARS];
enum DHudData {
COLOR_R,
COLOR_G,
COLOR_B,
Float:COORD_X,
Float:COORD_Y
};
enum GlowColors
{
Float:REVIVE_COLOR,
Float:PLANTING_COLOR
};
new Float:g_eGlowColors[GlowColors][3];
new g_eDHudData[Modes][DHudData];
new Float:g_fTime;
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
if(g_eCvars[CORPSE_SPRITE][0] != EOS)
precache_model(g_eCvars[CORPSE_SPRITE]);
new szHudColors[3][4];
if(parse(g_eCvars[REVIVE_COLORS], szHudColors[0], charsmax(szHudColors[]),
szHudColors[1], charsmax(szHudColors[]), szHudColors[2], charsmax(szHudColors[])) == 3) {
g_eDHudData[MODE_REVIVE][COLOR_R] = str_to_num(szHudColors[0]);
g_eDHudData[MODE_REVIVE][COLOR_G] = str_to_num(szHudColors[1]);
g_eDHudData[MODE_REVIVE][COLOR_B] = str_to_num(szHudColors[2]);
}
if(parse(g_eCvars[PLANTING_COLORS], szHudColors[0], charsmax(szHudColors[]),
szHudColors[1], charsmax(szHudColors[]), szHudColors[2], charsmax(szHudColors[])) == 3) {
g_eDHudData[MODE_PLANT][COLOR_R] = str_to_num(szHudColors[0]);
g_eDHudData[MODE_PLANT][COLOR_G] = str_to_num(szHudColors[1]);
g_eDHudData[MODE_PLANT][COLOR_B] = str_to_num(szHudColors[2]);
}
new szHudCoords[2][8];
if(parse(g_eCvars[REVIVE_COORDS], szHudCoords[0], charsmax(szHudCoords[]), szHudCoords[1], charsmax(szHudCoords[])) == 2) {
g_eDHudData[MODE_REVIVE][COORD_X] = str_to_float(szHudCoords[0]);
g_eDHudData[MODE_REVIVE][COORD_Y] = str_to_float(szHudCoords[1]);
}
if(parse(g_eCvars[PLANTING_COORDS], szHudCoords[0], charsmax(szHudCoords[]), szHudCoords[1], charsmax(szHudCoords[])) == 2) {
g_eDHudData[MODE_PLANT][COORD_X] = str_to_float(szHudCoords[0]);
g_eDHudData[MODE_PLANT][COORD_Y] = str_to_float(szHudCoords[1]);
}
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
if(g_eCvars[CORPSE_SPRITE][0] != EOS)
register_forward(FM_AddToFullPack, "AddToFullPack_Pre", false);
}
public plugin_cfg() {
g_fTime = get_pcvar_float(get_cvar_pointer("rt_revive_time"));
if(g_eCvars[REVIVE_GLOW][0] != EOS)
g_eGlowColors[REVIVE_COLOR] = parseHEXColor(g_eCvars[REVIVE_GLOW]);
if(g_eCvars[PLANTING_GLOW][0] != EOS)
g_eGlowColors[PLANTING_COLOR] = parseHEXColor(g_eCvars[PLANTING_GLOW]);
}
public AddToFullPack_Pre(es, e, ent, host, flags, player, pSet) {
if(player || !FClassnameIs(ent, CORPSE_SPRITE_CLASSNAME))
return FMRES_IGNORED;
if(TeamName:get_entvar(ent, var_team) != TeamName:get_member(host, m_iTeam)) {
forward_return(FMV_CELL, false);
return FMRES_SUPERCEDE;
}
return FMRES_IGNORED;
}
public rt_revive_start(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(eMode) {
case MODE_REVIVE: {
if(g_eCvars[SPECTATOR]) {
rg_internal_cmd(iPlayer, "specmode", "4");
set_entvar(iPlayer, var_iuser2, iActivator);
set_member(iPlayer, m_hObserverTarget, iActivator);
set_member(iPlayer, m_flNextObserverInput, get_gametime() + 1.25);
}
if(g_eCvars[NOTIFY_DHUD]) {
DisplayDHudMessage(iActivator, eMode, "RT_DHUD_REVIVE", iPlayer);
DisplayDHudMessage(iPlayer, eMode, "RT_DHUD_REVIVE2", iActivator);
}
if(g_eCvars[REVIVE_GLOW][0] != EOS)
rg_set_rendering(iEnt, kRenderFxGlowShell, g_eGlowColors[REVIVE_COLOR], kRenderNormal, 30.0);
}
case MODE_PLANT: {
if(g_eCvars[NOTIFY_DHUD])
DisplayDHudMessage(iActivator, eMode, "RT_DHUD_PLANTING", iPlayer);
if(g_eCvars[PLANTING_GLOW][0] != EOS)
rg_set_rendering(iEnt, kRenderFxGlowShell, g_eGlowColors[PLANTING_COLOR], kRenderNormal, 30.0);
}
}
}
public rt_revive_cancelled(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(g_eCvars[NOTIFY_DHUD]) {
if(iActivator != RT_NULLENT)
ClearDHudMessages(iActivator);
if(iPlayer != RT_NULLENT)
ClearDHudMessages(iPlayer);
}
switch(eMode)
{
case MODE_REVIVE:
{
if(g_eCvars[REVIVE_GLOW][0] != EOS)
rg_set_rendering(iEnt);
}
case MODE_PLANT:
{
if(g_eCvars[PLANTING_GLOW][0] != EOS)
rg_set_rendering(iEnt);
}
}
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(g_eCvars[NOTIFY_DHUD]) {
ClearDHudMessages(iActivator);
ClearDHudMessages(iPlayer);
}
switch(eMode)
{
case MODE_REVIVE:
{
static iMode;
iMode = get_entvar(iEnt, var_iuser3);
if(any:iMode != MODE_PLANT && g_eCvars[REVIVE_GLOW][0] != EOS)
rg_set_rendering(iEnt);
}
case MODE_PLANT:
{
if(g_eCvars[PLANTING_GLOW][0] != EOS)
rg_set_rendering(iEnt);
}
}
}
public rt_creating_corpse_end(const iEnt, const iPlayer, const Float:fVecOrigin[3]) {
if(g_eCvars[CORPSE_SPRITE][0] == EOS)
return;
new iEntSprite = rg_create_entity("info_target");
engfunc(EngFunc_SetOrigin, iEntSprite, fVecOrigin);
engfunc(EngFunc_SetModel, iEntSprite, g_eCvars[CORPSE_SPRITE]);
set_entvar(iEntSprite, var_classname, CORPSE_SPRITE_CLASSNAME);
set_entvar(iEntSprite, var_owner, iPlayer);
set_entvar(iEntSprite, var_iuser1, iEnt);
set_entvar(iEntSprite, var_team, TeamName:get_entvar(iEnt, var_team));
set_entvar(iEntSprite, var_scale, g_eCvars[SPRITE_SCALE]);
set_entvar(iEntSprite, var_renderfx, kRenderFxNone);
set_entvar(iEntSprite, var_rendercolor, Float:{255.0, 255.0, 255.0});
set_entvar(iEntSprite, var_rendermode, kRenderTransAlpha);
set_entvar(iEntSprite, var_renderamt, 255.0);
set_entvar(iEntSprite, var_nextthink, get_gametime() + 0.1);
SetThink(iEntSprite, "CorpseSprite_Think");
}
public CorpseSprite_Think(const iEnt) {
new iHostEnt = get_entvar(iEnt, var_iuser1);
if(is_nullent(iHostEnt) || !FClassnameIs(iHostEnt, DEAD_BODY_CLASSNAME)) {
RemoveCorpses(get_entvar(iEnt, var_owner), CORPSE_SPRITE_CLASSNAME);
return;
}
set_entvar(iEnt, var_nextthink, get_gametime() + 0.1);
}
stock rg_set_rendering(const id, const fx = kRenderFxNone, const Float:fColor[3] = {0.0, 0.0, 0.0}, const render = kRenderNormal, const Float:fAmount = 0.0)
{
set_entvar(id, var_renderfx, fx);
set_entvar(id, var_rendercolor, fColor);
set_entvar(id, var_rendermode, render);
set_entvar(id, var_renderamt, fAmount);
}
stock Float:parseHEXColor(const value[])
{
new Float:result[3];
if(value[0] != '#' && strlen(value) != 7)
return result;
result[0] = parse16bit(value[1], value[2]);
result[1] = parse16bit(value[3], value[4]);
result[2] = parse16bit(value[5], value[6]);
return result;
}
stock Float:parse16bit(ch1, ch2)
{
return float(parseHex(ch1) * 16 + parseHex(ch2));
}
stock parseHex(const ch)
{
switch(ch)
{
case '0'..'9': return (ch - '0');
case 'a'..'f': return (10 + ch - 'a');
case 'A'..'F': return (10 + ch - 'A');
}
return 0;
}
stock DisplayDHudMessage(const iPlayer, const Modes:eMode, any:...) {
new szMessage[128];
SetGlobalTransTarget(iPlayer);
vformat(szMessage, charsmax(szMessage), "%l", 3);
set_dhudmessage(g_eDHudData[eMode][COLOR_R], g_eDHudData[eMode][COLOR_G], g_eDHudData[eMode][COLOR_B],
g_eDHudData[eMode][COORD_X], g_eDHudData[eMode][COORD_Y], .holdtime = g_fTime);
show_dhudmessage(iPlayer, szMessage);
}
stock ClearDHudMessages(const iPlayer, const iChannel = 8) {
for(new i; i < iChannel; i++)
show_dhudmessage(iPlayer, "");
}
public CreateCvars() {
bind_pcvar_num(create_cvar(
"rt_spectator",
"1",
FCVAR_NONE,
"Automatically observe the resurrecting player",
true,
0.0,
true,
1.0),
g_eCvars[SPECTATOR]
);
bind_pcvar_num(create_cvar(
"rt_notify_dhud",
"1",
FCVAR_NONE,
"Notification above the timer(DHUD)",
true,
0.0,
true,
1.0),
g_eCvars[NOTIFY_DHUD]
);
bind_pcvar_string(create_cvar(
"rt_revive_dhud_colors",
"0 255 0",
FCVAR_NONE,
"DHUD's color at resurrection"),
g_eCvars[REVIVE_COLORS],
charsmax(g_eCvars[REVIVE_COLORS])
);
bind_pcvar_string(create_cvar(
"rt_revive_dhud_coords",
"-1.0 0.8",
FCVAR_NONE,
"DHUD's coordinates at resurrection"),
g_eCvars[REVIVE_COORDS],
charsmax(g_eCvars[REVIVE_COORDS])
);
bind_pcvar_string(create_cvar(
"rt_planting_dhud_colors",
"255 0 0",
FCVAR_NONE,
"DHUD's color at planting"),
g_eCvars[PLANTING_COLORS],
charsmax(g_eCvars[PLANTING_COLORS])
);
bind_pcvar_string(create_cvar(
"rt_planting_dhud_coords",
"-1.0 0.8",
FCVAR_NONE,
"DHUD's coordinates at planting"),
g_eCvars[PLANTING_COORDS],
charsmax(g_eCvars[PLANTING_COORDS])
);
bind_pcvar_string(create_cvar(
"rt_corpse_sprite",
"sprites/rt/corpse_sprite2.spr",
FCVAR_NONE,
"Resurrection sprite over a corpse. To disable the function, leave the cvar empty"),
g_eCvars[CORPSE_SPRITE],
charsmax(g_eCvars[CORPSE_SPRITE])
);
bind_pcvar_float(create_cvar(
"rt_sprite_scale",
"0.15",
FCVAR_NONE,
"Sprite scale",
true,
0.1,
true,
0.5),
g_eCvars[SPRITE_SCALE]
);
bind_pcvar_string(create_cvar(
"rt_revive_glow",
"#5da130",
FCVAR_NONE,
"The color of the corpse being resurrected(HEX)"),
g_eCvars[REVIVE_GLOW],
charsmax(g_eCvars[REVIVE_GLOW])
);
bind_pcvar_string(create_cvar(
"rt_planting_glow",
"#9b2d30",
FCVAR_NONE,
"The color of the corpse being planted(HEX)"),
g_eCvars[PLANTING_GLOW],
charsmax(g_eCvars[PLANTING_GLOW])
);
}
#include <amxmodx>
#include <hamsandwich>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Planting";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_planting.cfg";
enum CVARS {
Float:DAMAGE,
Float:RADIUS,
MAX_PLANTING
};
new g_eCvars[CVARS];
enum _:PlayerData {
PLANTING_COUNT
};
new g_ePlayerData[MAX_PLAYERS + 1][PlayerData];
new g_szModels[3];
public plugin_precache() {
g_szModels[0] = precache_model("sprites/zerogxplode.spr");
g_szModels[1] = precache_model("sprites/eexplo.spr");
g_szModels[2] = precache_model("sprites/fexplo.spr");
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
RegisterHookChain(RG_CSGameRules_CleanUpMap, "CSGameRules_CleanUpMap_Post", true);
}
public CSGameRules_CleanUpMap_Post() {
arrayset(g_ePlayerData[0][_:0], 0, sizeof(g_ePlayerData) * sizeof(g_ePlayerData[]));
}
public client_disconnected(iPlayer) {
g_ePlayerData[iPlayer][PLANTING_COUNT] = 0;
}
public rt_revive_start(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(eMode == MODE_PLANT) {
if(g_ePlayerData[iActivator][PLANTING_COUNT] >= g_eCvars[MAX_PLANTING]) {
NotifyClient(iActivator, print_team_red, "RT_PLANTING_COUNT");
return PLUGIN_HANDLED;
}
if(iMode == MODE_PLANT) {
NotifyClient(iActivator, print_team_red, "RT_IS_PLANTED", iPlayer);
return PLUGIN_HANDLED;
}
}
return PLUGIN_CONTINUE;
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(eMode) {
case MODE_REVIVE: {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(iMode == MODE_PLANT) {
new Float:fVecOrigin[3];
get_entvar(iActivator, var_origin, fVecOrigin);
MakeExplosionEffects(fVecOrigin);
new iPlanter = get_entvar(iEnt, var_iuser4);
for(new iVictim = 1, Float:fReduceDamage, Float:fVecEnd[3]; iVictim <= MaxClients; iVictim++) {
if(!is_user_alive(iVictim) || TeamName:get_member(iVictim, m_iTeam) != TeamName:get_member(iPlayer, m_iTeam))
continue;
get_entvar(iVictim, var_origin, fVecEnd);
if((fReduceDamage = (g_eCvars[DAMAGE] - vector_distance(fVecOrigin, fVecEnd) * (g_eCvars[DAMAGE] / g_eCvars[RADIUS]))) < 1.0)
continue;
set_member(iVictim, m_LastHitGroup, HITGROUP_GENERIC);
ExecuteHamB(Ham_TakeDamage, iVictim, iEnt, iPlanter, fReduceDamage, DMG_GRENADE | DMG_ALWAYSGIB);
}
RemoveCorpses(iPlayer, DEAD_BODY_CLASSNAME);
}
}
case MODE_PLANT: {
NotifyClient(iActivator, print_team_blue, "RT_PLANTING", iPlayer);
g_ePlayerData[iActivator][PLANTING_COUNT]++;
set_entvar(iEnt, var_iuser1, 0);
set_entvar(iEnt, var_iuser3, eMode);
set_entvar(iEnt, var_iuser4, iActivator);
}
}
}
stock MakeExplosionEffects(const Float:fVecOrigin[3]) {
message_begin_f(MSG_PAS, SVC_TEMPENTITY, fVecOrigin);
write_byte(TE_EXPLOSION);
write_coord_f(fVecOrigin[0]);
write_coord_f(fVecOrigin[1]);
write_coord_f(fVecOrigin[2] + 20.0);
write_short(g_szModels[2]);
write_byte(25);
write_byte(30);
write_byte(TE_EXPLFLAG_NONE);
message_end();
message_begin_f(MSG_PAS, SVC_TEMPENTITY, fVecOrigin);
write_byte(TE_EXPLOSION);
write_coord_f(fVecOrigin[0] + random_float(-64.0, 64.0));
write_coord_f(fVecOrigin[1] + random_float(-64.0, 64.0));
write_coord_f(fVecOrigin[2] + random_float(30.0, 35.0));
write_short(g_szModels[1]);
write_byte(30);
write_byte(30);
write_byte(TE_EXPLFLAG_NONE);
message_end();
for(new i; i < 3; i++) {
message_begin_f(MSG_PAS, SVC_TEMPENTITY, fVecOrigin);
write_byte(TE_SPRITE);
write_coord_f(fVecOrigin[0] + random_float(-256.0, 256.0));
write_coord_f(fVecOrigin[1] + random_float(-256.0, 256.0));
write_coord_f(fVecOrigin[2] + random_float(-10.0, 10.0));
write_short(g_szModels[i]);
write_byte(30);
write_byte(150);
message_end();
}
}
public CreateCvars() {
bind_pcvar_float(create_cvar(
"rt_explosion_damage",
"255.0",
FCVAR_NONE,
"Explosion damage",
true,
1.0),
g_eCvars[DAMAGE]
);
bind_pcvar_float(create_cvar(
"rt_explosion_radius",
"200.0",
FCVAR_NONE,
"Explosion radius",
true,
1.0),
g_eCvars[RADIUS]
);
bind_pcvar_num(create_cvar(
"rt_max_planting",
"3",
FCVAR_NONE,
"Maximum number of planting corpses per round",
true,
1.0),
g_eCvars[MAX_PLANTING]
);
}
#include <amxmodx>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Restrictions";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_restrictions.cfg";
#define m_iCurrentRound (get_member_game(m_iTotalRoundsPlayed) + 1)
enum CVARS {
ACCESS[32],
MAX_REVIVES,
MAX_SPAWNS,
NO_FIRE,
BOMB,
DUEL,
SURVIVOR,
MIN_ROUND,
NO_MOVE,
WIN_DIFF,
REVIVE_COST,
PLANTING_COST,
Float:REMAINING_TIME,
FORCE_FWD_MODE
};
new g_eCvars[CVARS];
enum _:PlayerData {
REVIVE_COUNT
};
const PREVENT_FLAGS = (PLAYER_PREVENT_CLIMB|PLAYER_PREVENT_JUMP);
new g_ePlayerData[MAX_PLAYERS + 1][PlayerData];
new g_iAccessFlags;
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
RegisterHookChain(RG_CSGameRules_CleanUpMap, "CSGameRules_CleanUpMap_Post", true);
}
public plugin_cfg() {
g_iAccessFlags = read_flags(g_eCvars[ACCESS]);
if(g_eCvars[NO_MOVE] == 1)
RegisterHookChain(RG_CBasePlayer_PreThink, "CBasePlayer_PreThink_Pre");
}
public CSGameRules_CleanUpMap_Post() {
arrayset(g_ePlayerData[0][_:0], 0, sizeof(g_ePlayerData) * sizeof(g_ePlayerData[]));
}
public client_disconnected(iPlayer) {
g_ePlayerData[iPlayer][REVIVE_COUNT] = 0;
}
public CBasePlayer_PreThink_Pre(const iPlayer) {
if(is_user_alive(iPlayer) && (get_entvar(iPlayer, var_iuser3) & PREVENT_FLAGS))
set_entvar(iPlayer, var_maxspeed, 1.0);
}
public rt_revive_start(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(~get_user_flags(iActivator) & g_iAccessFlags) {
NotifyClient(iActivator, print_team_red, "RT_NO_ACCESS");
return PLUGIN_HANDLED;
}
if(m_iCurrentRound < g_eCvars[MIN_ROUND]) {
NotifyClient(iActivator, print_team_red, "RT_MIN_ROUND", g_eCvars[MIN_ROUND]);
return PLUGIN_HANDLED;
}
if(g_eCvars[BOMB] && rg_is_bomb_planted()) {
NotifyClient(iActivator, print_team_red, "RT_BOMB");
return PLUGIN_HANDLED;
}
if(g_eCvars[DUEL] && rg_users_count(false)) {
NotifyClient(iActivator, print_team_red, "RT_DUEL");
return PLUGIN_HANDLED;
}
if(g_eCvars[SURVIVOR] && rg_users_count(true)) {
NotifyClient(iActivator, print_team_red, "RT_SURVIVOR");
return PLUGIN_HANDLED;
}
if(g_eCvars[REMAINING_TIME] && rg_get_remaining_time() <= g_eCvars[REMAINING_TIME]) {
NotifyClient(iActivator, print_team_red, "RT_REMAINING_TIME");
return PLUGIN_HANDLED;
}
if(g_eCvars[WIN_DIFF] && (rg_get_team_wins_row(g_eCvars[WIN_DIFF]) == TeamName:get_member(iActivator, m_iTeam))) {
NotifyClient(iActivator, print_team_red, "RT_WINS_DOMINATION");
return PLUGIN_HANDLED;
}
switch(eMode) {
case MODE_REVIVE: {
if(g_ePlayerData[iActivator][REVIVE_COUNT] >= g_eCvars[MAX_REVIVES]) {
NotifyClient(iActivator, print_team_red, "RT_REVIVE_COUNT");
return PLUGIN_HANDLED;
}
if(get_member(iPlayer, m_iNumSpawns) > g_eCvars[MAX_SPAWNS]) {
NotifyClient(iActivator, print_team_red, "RT_MAX_SPAWNS");
return PLUGIN_HANDLED;
}
if(get_member(iActivator, m_iAccount) < g_eCvars[REVIVE_COST]) {
NotifyClient(iActivator, print_team_red, "RT_NO_MONEY");
return PLUGIN_HANDLED;
}
}
case MODE_PLANT: {
if(get_member(iActivator, m_iAccount) < g_eCvars[PLANTING_COST]) {
NotifyClient(iActivator, print_team_red, "RT_NO_MONEY");
return PLUGIN_HANDLED;
}
}
}
if(g_eCvars[NO_MOVE] == 1) {
set_entvar(iActivator, var_iuser3, get_entvar(iActivator, var_iuser3) | PREVENT_FLAGS);
set_entvar(iActivator, var_velocity, NULL_VECTOR);
set_entvar(iActivator, var_maxspeed, 1.0);
}
if(g_eCvars[NO_FIRE])
set_member(iActivator, m_bIsDefusing, true);
return PLUGIN_CONTINUE;
}
public rt_revive_loop_pre(const iEnt, const iPlayer, const iActivator, const Float:fTimer, Modes:eMode) {
if(g_eCvars[BOMB] && rg_is_bomb_planted()) {
NotifyClient(iActivator, print_team_red, "RT_BOMB");
return PLUGIN_HANDLED;
}
if(g_eCvars[DUEL] && rg_users_count(false)) {
NotifyClient(iActivator, print_team_red, "RT_DUEL");
return PLUGIN_HANDLED;
}
if(g_eCvars[SURVIVOR] && rg_users_count(true)) {
NotifyClient(iActivator, print_team_red, "RT_SURVIVOR");
return PLUGIN_HANDLED;
}
if(g_eCvars[REMAINING_TIME] && rg_get_remaining_time() <= g_eCvars[REMAINING_TIME]) {
NotifyClient(iActivator, print_team_red, "RT_REMAINING_TIME");
return PLUGIN_HANDLED;
}
if(g_eCvars[NO_MOVE] == 2) {
new Float:fVecPlOrigin[3], Float:fVecEntOrigin[3];
get_entvar(iActivator, var_origin, fVecPlOrigin);
get_entvar(iEnt, var_vuser4, fVecEntOrigin);
if(vector_distance(fVecPlOrigin, fVecEntOrigin) > Float:get_entvar(iEnt, var_fuser2)) {
NotifyClient(iActivator, print_team_red, "RT_MAX_DISTANCE");
return PLUGIN_HANDLED;
}
}
return PLUGIN_CONTINUE;
}
public rt_revive_loop_post(const iEnt, const iPlayer, const iActivator, const Float:fTimer, Modes:eMode) {
if(g_eCvars[FORCE_FWD_MODE] && g_eCvars[NO_MOVE] == 1)
set_entvar(iActivator, var_maxspeed, 1.0);
}
public rt_revive_cancelled(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(iActivator == RT_NULLENT)
return;
if(g_eCvars[NO_MOVE] == 1) {
set_entvar(iActivator, var_iuser3, get_entvar(iActivator, var_iuser3) & ~PREVENT_FLAGS);
rg_reset_maxspeed(iActivator);
}
if(g_eCvars[NO_FIRE])
set_member(iActivator, m_bIsDefusing, false);
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(eMode) {
case MODE_REVIVE: {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(iMode != MODE_PLANT) {
g_ePlayerData[iActivator][REVIVE_COUNT]++;
rg_add_account(iActivator, -g_eCvars[REVIVE_COST]);
}
}
case MODE_PLANT: { rg_add_account(iActivator, -g_eCvars[PLANTING_COST]); }
}
if(g_eCvars[NO_MOVE] == 1) {
set_entvar(iActivator, var_iuser3, get_entvar(iActivator, var_iuser3) & ~PREVENT_FLAGS);
rg_reset_maxspeed(iActivator);
}
if(g_eCvars[NO_FIRE])
set_member(iActivator, m_bIsDefusing, false);
}
stock rg_users_count(const bool:bMode1x1 = false) {
new iAliveTs, iAliveCTs;
rg_initialize_player_counts(iAliveTs, iAliveCTs);
if(!bMode1x1 && (iAliveTs == 1 && iAliveCTs == 1))
return 1;
if(bMode1x1 && (iAliveTs == 1 || iAliveCTs == 1))
return 1;
return 0;
}
stock Float:rg_get_remaining_time() {
return (float(get_member_game(m_iRoundTimeSecs)) - get_gametime() + Float:get_member_game(m_fRoundStartTimeReal));
}
stock TeamName:rg_get_team_wins_row(const iWins) {
if(get_member_game(m_iNumConsecutiveCTLoses) >= iWins)
return TEAM_TERRORIST;
if(get_member_game(m_iNumConsecutiveTerroristLoses) >= iWins)
return TEAM_CT;
return TEAM_UNASSIGNED;
}
public CreateCvars() {
bind_pcvar_string(create_cvar(
"rt_access",
"",
FCVAR_NONE,
"Access flags for resurrection/planting"),
g_eCvars[ACCESS],
charsmax(g_eCvars[ACCESS])
);
bind_pcvar_num(create_cvar(
"rt_max_revives",
"3",
FCVAR_NONE,
"Maximum number of resurrections per round",
true,
1.0),
g_eCvars[MAX_REVIVES]
);
bind_pcvar_num(create_cvar(
"rt_max_spawns",
"2",
FCVAR_NONE,
"Maximum number of spawns per player per round",
true,
1.0),
g_eCvars[MAX_SPAWNS]
);
bind_pcvar_num(create_cvar(
"rt_no_fire",
"1",
FCVAR_NONE,
"Block shooting during resurrection/planting",
true,
0.0,
true,
1.0),
g_eCvars[NO_FIRE]
);
bind_pcvar_num(create_cvar(
"rt_bomb",
"1",
FCVAR_NONE,
"You cannot resurrect/plant if there is a bomb",
true,
0.0,
true,
1.0),
g_eCvars[BOMB]
);
bind_pcvar_num(create_cvar(
"rt_duel",
"1",
FCVAR_NONE,
"You can't resurrect/plant if there are 1x1 left",
true,
0.0,
true,
1.0),
g_eCvars[DUEL]
);
bind_pcvar_num(create_cvar(
"rt_survivor",
"0",
FCVAR_NONE,
"You cannot resurrect/plant if there is 1 live player left in one of the teams",
true,
0.0,
true,
1.0),
g_eCvars[SURVIVOR]
);
bind_pcvar_num(create_cvar(
"rt_min_round",
"1",
FCVAR_NONE,
"From which round is resurrection/planting available",
true,
1.0),
g_eCvars[MIN_ROUND]
);
bind_pcvar_num(create_cvar(
"rt_no_move",
"1",
FCVAR_NONE,
"Unable to move during resurrection/planting. 0 - allowed, 1 - not allowed, 2 - allowed, but close to corpse",
true,
0.0,
true,
2.0),
g_eCvars[NO_MOVE]
);
bind_pcvar_num(create_cvar(
"rt_revive_cost",
"0",
FCVAR_NONE,
"Cost of resurrection",
true,
0.0),
g_eCvars[REVIVE_COST]
);
bind_pcvar_num(create_cvar(
"rt_planting_cost",
"0",
FCVAR_NONE,
"Cost of planting",
true,
0.0),
g_eCvars[PLANTING_COST]
);
bind_pcvar_num(create_cvar(
"rt_wins_domination",
"5",
FCVAR_NONE,
"Prohibition of resurrection/planting for the dominant team(consecutive wins)",
true,
0.0),
g_eCvars[WIN_DIFF]
);
bind_pcvar_float(create_cvar(
"rt_remaining_time",
"30.0",
FCVAR_NONE,
"Prohibition of resurrection/planting until the end of the round",
true,
0.0),
g_eCvars[REMAINING_TIME]
);
new pCvar = get_cvar_pointer("rt_force_fwd_mode");
if(pCvar)
bind_pcvar_num(pCvar, g_eCvars[FORCE_FWD_MODE]);
}
#include <amxmodx>
#include <reapi>
#include <hamsandwich>
#include <fakemeta>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Model";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_revive_model.cfg";
enum CVARS {
MODEL_V[96],
};
new g_eCvars[CVARS];
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
if(g_eCvars[MODEL_V][0]) {
precache_model(g_eCvars[MODEL_V]);
UTIL_PrecacheSoundsFromModel(g_eCvars[MODEL_V]);
}
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, "mx?!");
if(g_eCvars[MODEL_V][0]) {
RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy_Post", true);
}
}
public plugin_cfg() {
if(!g_eCvars[MODEL_V][0]) {
return;
}
new pCvar = get_cvar_pointer("rt_force_fwd_mode"); // from rt_core.sma
if(!pCvar) {
return;
}
if(!get_pcvar_num(pCvar)) {
set_pcvar_num(pCvar, 1);
log_amx("Forcing 'rt_force_fwd_mode' cvar value to ^"1^" !");
}
}
public rt_revive_start_post(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(!g_eCvars[MODEL_V][0] || eMode != MODE_REVIVE) {
return;
}
set_entvar(iActivator, var_viewmodel, g_eCvars[MODEL_V]);
set_entvar(iActivator, var_weaponmodel, "");
set_member(iActivator, m_szAnimExtention, "knife");
const ANIM_DRAW = 3;
SetWeaponAnim(iActivator, ANIM_DRAW);
set_member(iActivator, m_flNextAttack, 9999.0);
new pWeapon = get_member(iActivator, m_pActiveItem);
if(pWeapon > 0) {
set_member(pWeapon, m_Weapon_flTimeWeaponIdle, 9999.0);
//set_member(pWeapon, m_Weapon_flNextPrimaryAttack, 9999.0);
//set_member(pWeapon, m_Weapon_flNextSecondaryAttack, 9999.0);
}
}
public rt_revive_loop_post(const iEnt, const iPlayer, const iActivator, const Float:fTimer, Modes:eMode) {
const Float:fAnimTime = 0.6; // 23 frames / 30 fps = 0.766, но нам не нужна полная анимация, обрезаем 0.166
const ANIM_USE = 1;
new Float:fGameTime = get_gametime();
new Float:fEndTime = fGameTime + fTimer;
if(g_eCvars[MODEL_V][0] && eMode == MODE_REVIVE && fGameTime > (fEndTime - fAnimTime) && get_entvar(iActivator, var_weaponanim) != ANIM_USE) {
SetWeaponAnim(iActivator, ANIM_USE);
}
}
public rt_revive_cancelled(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(eMode == MODE_REVIVE && iActivator != RT_NULLENT) {
TryResetReviveModel(iActivator);
}
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
if(eMode == MODE_REVIVE/* && iActivator != RT_NULLENT*/) {
TryResetReviveModel(iActivator);
}
}
TryResetReviveModel(pPlayer) {
if(!g_eCvars[MODEL_V][0] || !IsRiviveModelActive(pPlayer)) {
return;
}
new pWeapon = get_member(pPlayer, m_pActiveItem);
if(!is_nullent(pWeapon)) {
ExecuteHamB(Ham_Item_Deploy, pWeapon);
}
}
bool:IsRiviveModelActive(pPlayer) {
/*
if(!g_eCvars[MODEL_V][0]) {
return false;
}
*/
static szModel[96]
get_entvar(pPlayer, var_viewmodel, szModel, charsmax(szModel));
return bool:equal(szModel, g_eCvars[MODEL_V]);
}
public CBasePlayerWeapon_DefaultDeploy_Post(pWeapon, szViewModel[], szWeaponModel[], iAnim, szAnimExt[], skiplocal) {
if(!is_entity(pWeapon)) {
return;
}
new pPlayer = get_member(pWeapon, m_pPlayer);
if(rt_get_user_mode(pPlayer) == MODE_REVIVE) {
rt_reset_use(pPlayer);
}
}
CreateCvars() {
bind_pcvar_string(create_cvar(
"rt_revive_model_v",
"",
FCVAR_NONE,
"1st persion view model for revive process"),
g_eCvars[MODEL_V],
charsmax(g_eCvars[MODEL_V])
);
}
SetWeaponAnim(pPlayer, iAnimNum) {
set_entvar(pPlayer, var_weaponanim, iAnimNum);
message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = pPlayer);
write_byte(iAnimNum); // sequence number
write_byte(0); // weaponmodel bodygroup.
message_end();
}
// Автопрекеш звуков из модели: https://dev-cs.ru/resources/914/field?field=source
stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
new iFile;
if((iFile = fopen(szModelPath, "rt")))
{
new szSoundPath[64];
new iNumSeq, iSeqIndex;
new iEvent, iNumEvents, iEventIndex;
fseek(iFile, 164, SEEK_SET);
fread(iFile, iNumSeq, BLOCK_INT);
fread(iFile, iSeqIndex, BLOCK_INT);
for(new k, i = 0; i < iNumSeq; i++)
{
fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
fread(iFile, iNumEvents, BLOCK_INT);
fread(iFile, iEventIndex, BLOCK_INT);
fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
for(k = 0; k < iNumEvents; k++)
{
fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
fread(iFile, iEvent, BLOCK_INT);
fseek(iFile, 4, SEEK_CUR);
if(iEvent != 5004)
continue;
fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
if(strlen(szSoundPath))
{
strtolower(szSoundPath);
engfunc(EngFunc_PrecacheSound, szSoundPath);
}
}
}
}
fclose(iFile);
}
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Sounds";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_sounds.cfg";
public stock const INI_FILE[] = "addons/amxmodx/configs/rt_configs/rt_sounds.ini";
#define MAX_SOUNDS_PER_SECTION 10
#define MAX_SOUND_LENGTH 64
enum CVARS {
Float:SOUND_RADIUS,
NEARBY_PLAYERS,
FORCE_FWD_MODE
};
new g_eCvars[CVARS];
enum sections_struct {
SECTION_REVIVE_START,
SECTION_REVIVE_LOOP,
SECTION_REVIVE_END,
SECTION_PLANT_START,
SECTION_PLANT_LOOP,
SECTION_PLANT_END
};
new sections_struct:g_eCurrentSection;
new g_iSounds[sections_struct];
new g_szSounds[sections_struct][MAX_SOUNDS_PER_SECTION][MAX_SOUND_LENGTH];
new g_iTicks[MAX_PLAYERS + 1];
public plugin_precache() {
register_plugin(PLUGIN, VERSION, AUTHORS);
if(!file_exists(INI_FILE)) {
set_fail_state("[RT Sounds] File ^"%s^" not found", INI_FILE);
return;
}
new INIParser:iParser = INI_CreateParser();
INI_SetReaders(iParser, "ReadKeyValue", "ReadNewSection");
INI_ParseFile(iParser, INI_FILE);
INI_DestroyParser(iParser);
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
}
public rt_revive_start(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
g_iTicks[iActivator] = 0;
switch(eMode) {
case MODE_REVIVE: { PlaybackSound(iEnt, iPlayer, iActivator, SECTION_REVIVE_START); }
case MODE_PLANT: { PlaybackSound(iEnt, iPlayer, iActivator, SECTION_PLANT_START); }
}
}
public rt_revive_loop_post(const iEnt, const iPlayer, const iActivator, const Float:fTimer, Modes:eMode) {
if(!g_eCvars[FORCE_FWD_MODE] || ++g_iTicks[iActivator] == 10) {
g_iTicks[iActivator] = 0;
switch(eMode) {
case MODE_REVIVE: { PlaybackSound(iEnt, iPlayer, iActivator, SECTION_REVIVE_LOOP); }
case MODE_PLANT: { PlaybackSound(iEnt, iPlayer, iActivator, SECTION_PLANT_LOOP); }
}
}
}
public rt_revive_end(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(eMode) {
case MODE_REVIVE: {
new Modes:iMode = Modes:get_entvar(iEnt, var_iuser3);
if(iMode != MODE_PLANT)
PlaybackSound(iEnt, iPlayer, iActivator, SECTION_REVIVE_END);
}
case MODE_PLANT: { PlaybackSound(iEnt, iPlayer, iActivator, SECTION_PLANT_END); }
}
}
public bool:ReadNewSection(INIParser:iParser, const szSection[], bool:bInvalidTokens, bool:bCloseBracket) {
if(!bCloseBracket) {
log_error(AMX_ERR_NATIVE, "Closing bracket was not detected! Current section name '%s'.", szSection);
return false;
}
if(equal(szSection, "revive_start")) {
g_eCurrentSection = SECTION_REVIVE_START;
return true;
} else if(equal(szSection, "revive_loop")) {
g_eCurrentSection = SECTION_REVIVE_LOOP;
return true;
} else if(equal(szSection, "revive_end")) {
g_eCurrentSection = SECTION_REVIVE_END;
return true;
} else if(equal(szSection, "plant_start")) {
g_eCurrentSection = SECTION_PLANT_START;
return true;
} else if(equal(szSection, "plant_loop")) {
g_eCurrentSection = SECTION_PLANT_LOOP;
return true;
} else if(equal(szSection, "plant_end")) {
g_eCurrentSection = SECTION_PLANT_END;
return true;
}
return false;
}
public bool:ReadKeyValue(INIParser:iParser, const szKey[], const szValue[]) {
if(szKey[0] == EOS)
return false;
new szSound[MAX_SOUND_LENGTH];
copy(szSound, charsmax(szSound), szKey);
trim(szSound);
copy(g_szSounds[g_eCurrentSection][g_iSounds[g_eCurrentSection]++], charsmax(g_szSounds[][]), szSound);
precache_sound(szSound);
return true;
}
stock PlaybackSound(const iEnt, const iPlayer, const iActivator, const sections_struct:iSoundSection) {
if(g_iSounds[iSoundSection]) {
if(g_eCvars[NEARBY_PLAYERS] == 2 || (g_eCvars[NEARBY_PLAYERS] && (iSoundSection == SECTION_REVIVE_END || iSoundSection == SECTION_PLANT_END)))
PlaybackSoundNearbyPlayers(iEnt, g_szSounds[iSoundSection][random(g_iSounds[iSoundSection])]);
else if(!g_eCvars[NEARBY_PLAYERS]) {
rg_send_audio(iActivator, g_szSounds[iSoundSection][random(g_iSounds[iSoundSection])]);
rg_send_audio(iPlayer, g_szSounds[iSoundSection][random(g_iSounds[iSoundSection])]);
}
}
}
stock PlaybackSoundNearbyPlayers(const iPlayer, const szSound[]) {
new iEnt = RT_NULLENT;
new Float:fVecOrigin[3];
get_entvar(iPlayer, var_vuser4, fVecOrigin);
while((iEnt = engfunc(EngFunc_FindEntityInSphere, iEnt, fVecOrigin, g_eCvars[SOUND_RADIUS])) > 0)
if(ExecuteHam(Ham_IsPlayer, iEnt))
rg_send_audio(iEnt, szSound);
}
public CreateCvars() {
bind_pcvar_float(create_cvar(
"rt_sound_radius",
"250.0",
FCVAR_NONE,
"The radius in which to count the nearest players",
true,
1.0),
g_eCvars[SOUND_RADIUS]
);
bind_pcvar_num(create_cvar(
"rt_nearby_players",
"0",
FCVAR_NONE,
"Play the resurrection/landing sound for nearby players. 0 - off, 1 - only ending sounds, 2 - all sounds",
true,
0.0,
true,
2.0),
g_eCvars[NEARBY_PLAYERS]
);
new pCvar = get_cvar_pointer("rt_force_fwd_mode");
if(pCvar)
bind_pcvar_num(pCvar, g_eCvars[FORCE_FWD_MODE]);
}
#include <amxmodx>
#include <reapi>
#include <rt_api>
public stock const PLUGIN[] = "Revive Teammates: Timer";
public stock const CFG_FILE[] = "addons/amxmodx/configs/rt_configs/rt_timer.cfg";
enum CVARS {
TIMER_TYPE,
REVIVE_COLORS[MAX_COLORS_LENGTH],
REVIVE_COORDS[MAX_COORDS_LENGTH],
PLANTING_COLORS[MAX_COLORS_LENGTH],
PLANTING_COORDS[MAX_COORDS_LENGTH],
FORCE_FWD_MODE
};
new g_eCvars[CVARS];
enum HudData {
COLOR_R,
COLOR_G,
COLOR_B,
Float:COORD_X,
Float:COORD_Y
};
new g_eHudData[Modes][HudData];
enum TimeData {
Float:GLOBAL_TIME,
CEIL_TIME,
Float:START_TIME,
};
new g_eTimeData[TimeData];
new const TIMER_BEGIN[] = "[ | ";
new const TIMER_ADD[] = "- ";
new const TIMER_END[] = "]";
new const TIMER_REPLACE_SYMB[] = "| -";
new const TIMER_REPLACE_WITH[] = "| |";
new g_szTimer[MAX_PLAYERS + 1][64];
new g_iHudSyncObj;
new g_iTicks[MAX_PLAYERS + 1];
public plugin_precache() {
CreateCvars();
server_cmd("exec %s", CFG_FILE);
server_exec();
new szHudColors[3][4];
if(parse(g_eCvars[REVIVE_COLORS], szHudColors[0], charsmax(szHudColors[]),
szHudColors[1], charsmax(szHudColors[]), szHudColors[2], charsmax(szHudColors[])) == 3) {
g_eHudData[MODE_REVIVE][COLOR_R] = str_to_num(szHudColors[0]);
g_eHudData[MODE_REVIVE][COLOR_G] = str_to_num(szHudColors[1]);
g_eHudData[MODE_REVIVE][COLOR_B] = str_to_num(szHudColors[2]);
}
if(parse(g_eCvars[PLANTING_COLORS], szHudColors[0], charsmax(szHudColors[]),
szHudColors[1], charsmax(szHudColors[]), szHudColors[2], charsmax(szHudColors[])) == 3) {
g_eHudData[MODE_PLANT][COLOR_R] = str_to_num(szHudColors[0]);
g_eHudData[MODE_PLANT][COLOR_G] = str_to_num(szHudColors[1]);
g_eHudData[MODE_PLANT][COLOR_B] = str_to_num(szHudColors[2]);
}
new szHudCoords[2][8];
if(parse(g_eCvars[REVIVE_COORDS], szHudCoords[0], charsmax(szHudCoords[]), szHudCoords[1], charsmax(szHudCoords[])) == 2) {
g_eHudData[MODE_REVIVE][COORD_X] = str_to_float(szHudCoords[0]);
g_eHudData[MODE_REVIVE][COORD_Y] = str_to_float(szHudCoords[1]);
}
if(parse(g_eCvars[PLANTING_COORDS], szHudCoords[0], charsmax(szHudCoords[]), szHudCoords[1], charsmax(szHudCoords[])) == 2) {
g_eHudData[MODE_PLANT][COORD_X] = str_to_float(szHudCoords[0]);
g_eHudData[MODE_PLANT][COORD_Y] = str_to_float(szHudCoords[1]);
}
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHORS);
register_dictionary("rt_library.txt");
if(!g_eCvars[TIMER_TYPE])
g_iHudSyncObj = CreateHudSyncObj();
g_eTimeData[GLOBAL_TIME] = get_pcvar_float(get_cvar_pointer("rt_revive_time"));
g_eTimeData[CEIL_TIME] = floatround(g_eTimeData[GLOBAL_TIME], floatround_ceil);
g_eTimeData[START_TIME] = (1.0 - g_eTimeData[GLOBAL_TIME] / float(g_eTimeData[CEIL_TIME])) * 100.0;
}
public rt_revive_start(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
g_iTicks[iActivator] = 0;
switch(g_eCvars[TIMER_TYPE]) {
case 0: {
formatex(g_szTimer[iPlayer], charsmax(g_szTimer[]), TIMER_BEGIN);
for(new i; i < floatround(g_eTimeData[GLOBAL_TIME]); i++)
add(g_szTimer[iPlayer], charsmax(g_szTimer[]), TIMER_ADD);
add(g_szTimer[iPlayer], charsmax(g_szTimer[]), TIMER_END);
DisplayHudMessage(iPlayer, iActivator, eMode);
}
case 1: {
rg_send_bartime2(iActivator, g_eTimeData[CEIL_TIME], g_eTimeData[START_TIME]);
if(eMode == MODE_REVIVE && is_user_connected(iPlayer))
rg_send_bartime2(iPlayer, g_eTimeData[CEIL_TIME], g_eTimeData[START_TIME]);
}
}
}
public rt_revive_loop_post(const iEnt, const iPlayer, const iActivator, const Float:fTimer, Modes:eMode) {
if(!g_eCvars[FORCE_FWD_MODE] || ++g_iTicks[iActivator] == 10) {
g_iTicks[iActivator] = 0;
if(!g_eCvars[TIMER_TYPE]) {
replace(g_szTimer[iPlayer], charsmax(g_szTimer[]), TIMER_REPLACE_SYMB, TIMER_REPLACE_WITH);
DisplayHudMessage(iPlayer, iActivator, eMode);
}
}
}
public rt_revive_cancelled(const iEnt, const iPlayer, const iActivator, const Modes:eMode) {
switch(g_eCvars[TIMER_TYPE]) {
case 0: {
if(iActivator != RT_NULLENT)
ClearSyncHud(iActivator, g_iHudSyncObj);
}
case 1: {
if(iActivator != RT_NULLENT)
rg_send_bartime(iActivator, 0);
if(eMode == MODE_REVIVE && iPlayer != RT_NULLENT)
rg_send_bartime(iPlayer, 0);
}
}
}
stock DisplayHudMessage(const iPlayer, const iActivator, const Modes:eMode) {
set_hudmessage(g_eHudData[eMode][COLOR_R], g_eHudData[eMode][COLOR_G], g_eHudData[eMode][COLOR_B],
g_eHudData[eMode][COORD_X], g_eHudData[eMode][COORD_Y], .holdtime = g_eTimeData[GLOBAL_TIME]);
ShowSyncHudMsg(iActivator, g_iHudSyncObj, g_szTimer[iPlayer]);
}
public CreateCvars() {
bind_pcvar_num(create_cvar(
"rt_timer_type",
"1",
FCVAR_NONE,
"0 - HUD, 1 - bartime(orange line)",
true,
0.0,
true,
1.0),
g_eCvars[TIMER_TYPE]
);
bind_pcvar_string(create_cvar(
"rt_revive_hud_colors",
"0 255 0",
FCVAR_NONE,
"HUD's colors at resurrection"),
g_eCvars[REVIVE_COLORS],
charsmax(g_eCvars[REVIVE_COLORS])
);
bind_pcvar_string(create_cvar(
"rt_revive_hud_coords",
"-1.0 0.6",
FCVAR_NONE,
"HUD's coordinates at resurrection"),
g_eCvars[REVIVE_COORDS],
charsmax(g_eCvars[REVIVE_COORDS])
);
bind_pcvar_string(create_cvar(
"rt_planting_hud_colors",
"255 0 0",
FCVAR_NONE,
"HUD's colors at planting"),
g_eCvars[PLANTING_COLORS],
charsmax(g_eCvars[PLANTING_COLORS])
);
bind_pcvar_string(create_cvar(
"rt_planting_hud_coords",
"-1.0 0.6",
FCVAR_NONE,
"HUD's coordinates at planting"),
g_eCvars[PLANTING_COORDS],
charsmax(g_eCvars[PLANTING_COORDS])
);
new pCvar = get_cvar_pointer("rt_force_fwd_mode");
if(pCvar)
bind_pcvar_num(pCvar, g_eCvars[FORCE_FWD_MODE]);
}