Код:
#include <amxmodx>
#include <fakemeta>
// Here you can adjust the required admin level if needed
// there is a list of all levels http://www.amxmodx.org/funcwiki.php?go=mod...d=1#const_admin
#define REQUIRED_ADMIN_LEVEL ADMIN_BAN
//--------------------------------------------------------------------------------------------------
#define PLUGIN "Admin ESP"
#define VERSION "1.5b_m"
#define AUTHOR "KoST"
#define OFFSET_TEAM 114
new const g_szPlugin[] = PLUGIN; // Global this since it is used throughout
new pcvar_esp, pcvar_esp_timer;
new esp_colors[5][3] = {{0,255,0}, {100,60,60}, {60,60,100}, {255,0,255}, {128,128,128}};
new bool:admin[33]; // is/is not admin
new bool:first_person[33]; // is/is not in first person view
new bool:ducking[33]; // is/is not player ducked
new bool:enabled[33]; // has esp on
new spec[33]; // spec[player_id]=the players id if
new laser; // precached model
new max_players; // if you start hlds with +maxplayers 20 for example this would be 20
new damage_done_to[33]; // damage_done_to[p1]=p2 // p1 has hit p2
new view_target[33]; // attackers victim
new ForwardCmdStart
public plugin_precache() {
laser = precache_model("sprites/laserbeam.spr");
}
public plugin_init() {
register_plugin(g_szPlugin, VERSION, AUTHOR);
server_print("^n^t%s v%s, Copyright © 2006 by %s^n", g_szPlugin, VERSION, AUTHOR);
// cvars
pcvar_esp = register_cvar("esp", "1");
pcvar_esp_timer = register_cvar("esp_timer", "0.1");
register_cvar("aesp_version", VERSION, FCVAR_SERVER|FCVAR_UNLOGGED|FCVAR_SPONLY);
// client commands
register_clcmd("esp_toggle", "cmd_esp_toggle", REQUIRED_ADMIN_LEVEL, "Toggle ESP on/off");
register_clcmd("say /esp_toggle", "cmd_esp_toggle", REQUIRED_ADMIN_LEVEL, "Toggle ESP on/off");
// events
register_event("StatusValue", "spec_target", "bd", "1=2");
register_event("SpecHealth2", "spec_target", "bd");
register_event("TextMsg", "spec_mode", "b", "2&#Spec_Mode");
register_event("Damage", "event_Damage", "b", "2!0", "3=0", "4!0");
register_event("ResetHUD", "reset_hud_alive", "be");
max_players = get_maxplayers();
// start esp_timer for the first time
set_task(1.0, "esp_timer");
}
public client_putinserver(id) {
first_person[id] = false;
new args[1];
args[0] = id;
set_task(4.0, "delayed_putinserver", id + 100, args, 1);
}
public delayed_putinserver(args[0])
{
new id = args[0];
if (!is_user_connected(id))
{
return PLUGIN_HANDLED;
}
if (get_user_flags(id) & REQUIRED_ADMIN_LEVEL)
{
admin[id] = true;
init_admin_options(id);
} else {
admin[id] = false;
}
return PLUGIN_CONTINUE;
}
public client_disconnect(id) {
save2vault(id);
admin[id] = false;
spec[id] = 0;
remove_task(id + 100);
}
public reset_hud_alive(id) {
spec[id] = 0;
}
public cmd_esp_toggle(id) {
if (admin[id] && get_pcvar_num(pcvar_esp) == 1) {
change_esp_status(id, !enabled[id]);
}
}
public event_Damage(id) {
if (id>0) {
new attacker = get_user_attacker(id)
if (attacker > 0 && attacker <= max_players) {
if (view_target[attacker] == id) {
damage_done_to[attacker] = id;
}
}
}
return PLUGIN_CONTINUE;
}
public spec_mode(id) {
// discover if in first_person_view
new specMode[12]
read_data(2, specMode, 11);
if(equal(specMode, "#Spec_Mode4")) {
first_person[id] = true;
ForwardCmdStart = register_forward(FM_CmdStart,"cmdStart");
} else {
first_person[id] = false;
unregister_forward(FM_CmdStart,ForwardCmdStart);
}
return PLUGIN_CONTINUE;
}
public spec_target(id) {
if (id > 0) {
new target = read_data(2);
if (target != 0) {
spec[id] = target;
}
}
return PLUGIN_CONTINUE;
}
init_admin_options(id) {
enabled[id] = true;
load_vault_data(id);
}
save2vault(id) {
if (admin[id]) {
new authid[35];
get_user_authid (id,authid,34);
new tmp[3];
tmp[0] = (enabled[id]) ? '1' : '0';
new key[41];
formatex(key, 40, "AESPmini_%s", authid);
set_vaultdata(key, tmp);
}
}
load_vault_data(id) {
if (admin[id]) {
new data[3];
new authid[35];
get_user_authid (id,authid,34);
new key[41];
formatex(key,40, "AESPmini_%s", authid);
get_vaultdata(key,data,2);
if (strlen(data) > 0) {
enabled[id] = (data[0]=='1');
}
}
}
change_esp_status(id, bool:on) {
if (on) {
enabled[id] = true;
client_print(id, print_chat, "[%s] ON", g_szPlugin);
} else {
enabled[id] = false;
client_print(id, print_chat, "[%s] OFF", g_szPlugin);
}
}
public cmdStart(id)
{
if (!is_user_connected(id)) return FMRES_IGNORED;
static button;
button = pev(id, pev_button);
if (button==0) return FMRES_IGNORED; // saves a lot of cpu
static oldbutton;
oldbutton = pev(id, pev_oldbuttons);
if (button & IN_DUCK) {
ducking[id] = true;
} else {
ducking[id] = false;
}
if (get_pcvar_num(pcvar_esp) == 1)
{
if (admin[id]) {
if (first_person[id] && !is_user_alive(id)) {
if ((button & IN_FORWARD) && !(oldbutton & IN_FORWARD) && !enabled[id]) {
change_esp_status(id, true);
}
if ((button & IN_BACK) && !(oldbutton & IN_BACK) && enabled[id]) {
change_esp_status(id, false);
}
}
}
}
return FMRES_HANDLED;
}
public esp_timer() {
if (get_pcvar_num(pcvar_esp) != 1) { // if esp is not 1, it is off
set_task(1.0, "esp_timer"); // check for reactivation in 1 sec intervals
return PLUGIN_CONTINUE;
}
static spec_id, Float:my_origin[3], my_team, s,
target_team, Float:target_origin[3], Float:distance, Float:v_middle[3], Float:v_hitpoint[3],
Float:distance_to_hitpoint, Float:scaled_bone_len, Float:scaled_bone_width, Float:v_bone_start[3],
Float:v_bone_end[3], Float:offset_vector[3], Float:eye_level[3], Float:distance_target_hitpoint,
actual_bright, color
for (new i = 1; i <= max_players; i++) { // loop through players
if (enabled[i] && first_person[i] && is_user_connected(i) && admin[i] && (!is_user_alive(i)) && (spec[i] > 0) && is_user_alive(spec[i])) { // :)
spec_id = spec[i];
pev(i, pev_origin, my_origin); // get origin of spectating admin
// get team of spectated :)
my_team = get_pdata_int(spec_id, OFFSET_TEAM);
for (s = 1; s <= max_players; s++) { // loop through the targets
if (is_user_alive(s)) { // target must be alive
// get team of target
target_team = get_pdata_int(s, OFFSET_TEAM);
if (!(target_team == 3)) { //if not spectator
if (spec_id != s) { // do not target myself
// if the target is in the other team and not spectator
if (((my_team != target_team && (target_team == 1 || target_team == 2)) ))
{
// get origin of target
pev(s, pev_origin, target_origin);
// get distance from me to target
distance = vector_distance(my_origin, target_origin);
// get vector from me to target
subVec(target_origin, my_origin, v_middle);
// trace from me to target, getting hitpoint
engfunc(EngFunc_TraceLine, my_origin, target_origin, 1, -1, 0);
get_tr2(0, TR_vecEndPos, v_hitpoint);
// get distance from me to hitpoint (nearest wall)
distance_to_hitpoint = vector_distance(my_origin, v_hitpoint);
// scale
if (ducking[spec_id]) {
scaled_bone_len = distance_to_hitpoint / distance * (50.0-18.0);
} else {
scaled_bone_len = distance_to_hitpoint / distance * 50.0;
}
scaled_bone_len = distance_to_hitpoint / distance * 50.0;
scaled_bone_width = distance_to_hitpoint / distance * 150.0;
// get the point 10.0 units away from wall
normalize(v_middle, offset_vector, distance_to_hitpoint - 10.0); // offset from wall
// set to eye level
copyVec(my_origin, eye_level);
if (ducking[spec_id]) {
eye_level[2] += 12.3
} else {
eye_level[2] += 17.5
}
addVec(offset_vector, eye_level);
// start and end of green box
copyVec(offset_vector, v_bone_start);
copyVec(offset_vector, v_bone_end);
v_bone_end[2] -= scaled_bone_len;
distance_target_hitpoint = distance - distance_to_hitpoint;
actual_bright = 255;
// Draw BOX
// this is to make green box darker if distance is larger
if (distance_target_hitpoint < 2040.0) {
actual_bright = (255 - floatround(distance_target_hitpoint / 12.0));
} else {
actual_bright = 72;
}
if (distance_to_hitpoint != distance) { // if no line of sight
color = 0;
} else { // if line of sight
color = target_team;
}
if (damage_done_to[spec_id] == s) {
color = 3;
damage_done_to[spec_id] = 0;
}
make_TE_BEAMPOINTS(i, color, v_bone_start, v_bone_end, floatround(scaled_bone_width), actual_bright);
}
}
}
}
} // inner player loop end
}
}
set_task(get_pcvar_float(pcvar_esp_timer), "esp_timer"); // keep it going
return PLUGIN_CONTINUE;
}
// Vector Operations -------------------------------------------------------------------------------
Float:getVecLen(Float:Vec[3]) {
new Float:VecNull[3] = {0.0,0.0,0.0};
new Float:len = vector_distance(Vec, VecNull);
return len;
}
normalize(Float:Vec[3], Float:Ret[3], Float:multiplier) {
new Float:len = getVecLen(Vec);
copyVec(Vec, Ret);
Ret[0] /= len;
Ret[1] /= len;
Ret[2] /= len;
Ret[0] *= multiplier;
Ret[1] *= multiplier;
Ret[2] *= multiplier;
}
copyVec(Float:Vec[3], Float:Ret[3]) {
Ret[0] = Vec[0];
Ret[1] = Vec[1];
Ret[2] = Vec[2];
}
subVec(Float:Vec1[3], Float:Vec2[3], Float:Ret[3]) {
Ret[0] = Vec1[0] - Vec2[0];
Ret[1] = Vec1[1] - Vec2[1];
Ret[2] = Vec1[2] - Vec2[2];
}
addVec(Float:Vec1[3], Float:Vec2[3]) {
Vec1[0] += Vec2[0];
Vec1[1] += Vec2[1];
Vec1[2] += Vec2[2];
}
// Temporary Entities ------------------------------------------------------------------------------
// there is a list of much more temp entities at: http://djeyl.net/forum/index.php?act=Attac...t&id=290870
// all messages are sent with MSG_ONE_UNRELIABLE flag to avoid overflow in case of very low esp_timer setting and much targets
make_TE_BEAMPOINTS(id,color, Float:Vec1[3], Float:Vec2[3], width, brightness) {
message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, {0,0,0}, id); //message begin
write_byte(0);
write_coord(floatround(Vec1[0])); // start position
write_coord(floatround(Vec1[1]));
write_coord(floatround(Vec1[2]));
write_coord(floatround(Vec2[0])); // end position
write_coord(floatround(Vec2[1]));
write_coord(floatround(Vec2[2]));
write_short(laser); // sprite index
write_byte(3); // starting frame
write_byte(0); // frame rate in 0.1's
write_byte(floatround(get_pcvar_float(pcvar_esp_timer) * 10)); // life in 0.1's
write_byte(width); // line width in 0.1's
write_byte(0); // noise amplitude in 0.01's
write_byte(esp_colors[color][0]);
write_byte(esp_colors[color][1]);
write_byte(esp_colors[color][2]);
write_byte(brightness); // brightness)
write_byte(0); // scroll speed in 0.1's
message_end();
}