#include <amxmodx>
#include <amxmisc>
#include <reapi>
#if !defined MAX_MAPNAME_LENGTH
#define MAX_MAPNAME_LENGTH 64
#endif
#define ACCESS ADMIN_RCON //доступ к меню перемещения
#define SHOW_COORDS //режим показа координат в чат по всем осям после изменений (x, y ,z)
new const PLUGIN_VER[] = "1.0.2";
new const PLUGIN_DIR[] = "move_entities";
new Float:Move[MAX_PLAYERS + 1], Sign[MAX_PLAYERS + 1], Array:OldSaveCoords, Array:NewSaveCoords, Array:SaveClassname, Array:Sign;
new OldCheck[MAX_PLAYERS+1], NewCheck[MAX_PLAYERS+1], ArrayNum[MAX_PLAYERS+1];
public plugin_init()
{
register_plugin("Move entities", PLUGIN_VER, "wellasgood");
register_dictionary("move_entities.txt");
OldSaveCoords = ArrayCreate(128);
NewSaveCoords = ArrayCreate(128);
SaveClassname = ArrayCreate(32);
Sign = ArrayCreate(6);
new const COMMANDS[][] =
{
"say m-m",
"say /move-menu",
"move"
};
new i;
while(i < sizeof COMMANDS)
{
register_clcmd(COMMANDS[i++], "@MoveMenu");
}
register_menu("@MoveMenu", 1023, "@Handle_MoveMenu", 0);
register_concmd("MoveValue", "@MoveHandler");
register_cvar("move_entities_version", PLUGIN_VER, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED);
ReadAndSaveCoordinate(false);
SearchAndChangeOfPositions();
}
public client_connect(id)
{
OldCheck[id] = 0;
NewCheck[id] = 0;
ArrayNum[id] = 0;
}
@MoveMenu(id)
{
if(~get_user_flags(id) & ACCESS) return 0;
new Menu[MAX_MENU_LENGTH], Keys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0;
new Len = formatex(Menu, charsmax(Menu), "%L^n^n", id, "MOVE_ENT_MENU_TITLE");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[1] \y# \w%L: \r[\y%L\r]^n", id, "MOVE_ENT_MENU_ITEM1", id, fmt("MOVE_ENT_MENU_ITEM1_%d", Sign[id]));
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[2] \y# \w%L\w: \r[\y%.2f\r]^n", id, "MOVE_ENT_MENU_ITEM2", Move[id]);
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \w%L^n^n", id, "MOVE_ENT_MENU_ITEM3");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[3] \y# \wX++^n");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[4] \y# \wX--^n");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[5] \y# \wY++^n");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[6] \y# \wY--^n");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[7] \y# \wZ++^n");
Len += formatex(Menu[Len], charsmax(Menu) - Len, "\r[8] \y# \wZ--^n^n");
formatex(Menu[Len], charsmax(Menu) - Len, "\r[0] \y# \w%L", id, "MENU_EXIT");
return show_menu(id, Keys, Menu, -1, "@MoveMenu");
}
@Handle_MoveMenu(id, Keys)
{
switch(Keys)
{
case 0:
{
Sign[id] = (Sign[id] + 1) % 2;
}
case 1:
{
client_cmd(id, "messagemode ^"MoveValue^"");
}
case 1:
{
ReadAndSaveCoordinate(true);
}
case 9:
{
return;
}
default:
{
MoveEntity(id, Keys);
}
}
@MoveMenu(id);
}
@MoveHandler(id)
{
if(~get_user_flags(id) & ACCESS) return;
new String[64];
read_argv(1, String, charsmax(String));
new Part1[32], Part2[32];
strtok(String, Part1, charsmax(Part1), Part2, charsmax(Part2), '.');
if(is_str_num(Part1) && is_str_num(Part2))
{
Move[id] = str_to_float(String);
}
@MoveMenu(id);
}
MoveEntity(id, mode, ent = 0)
{
get_user_aiming(id, ent, _, 9999);
if(ent == 0) return;
new Float:DataCoord[3];
get_entvar(ent, Sign[id] == 1 ? var_origin : var_angles, DataCoord);
if(OldCheck[id] != ent)
{
new Float:NewCoords1[3];
get_entvar(ent, Sign[id] == 1 ? var_angles : var_origin, NewCoords1);
ArrayPushString(OldSaveCoords, fmt("%s %f %f %f %f %f %f", Sign[id] == 1 ? "O" : "A", DataCoord[0], DataCoord[1], DataCoord[2], NewCoords1[0], NewCoords1[1], NewCoords1[2]));
OldCheck[id] = ent;
}
switch(mode)
{
case 2: DataCoord[0] += Move[id];
case 3: DataCoord[0] -= Move[id];
case 4: DataCoord[1] += Move[id];
case 5: DataCoord[1] -= Move[id];
case 6: DataCoord[2] += Move[id];
case 7: DataCoord[2] -= Move[id];
}
set_entvar(ent, Sign[id] == 1 ? var_origin : var_angles, DataCoord);
#if defined SHOW_COORDS
client_print_color(id, print_team_default, "%l ^1%s ^3X ^4%.2f ^1| ^3Y ^4%.2f ^1| ^3Z ^4%.2f", "MOVE_ENT_CHAT_PREFIX", Sign[id] == 1 ? "Origin:" : "Angles:", DataCoord[0], DataCoord[1], DataCoord[2]);
#endif
new Float:NewCoords2[3];
get_entvar(ent, Sign[id] == 1 ? var_angles : var_origin, NewCoords2);
if(NewCheck[id] != ent)
{
ArrayPushString(NewSaveCoords, fmt("%s %f %f %f %f %f %f", Sign[id] == 1 ? "O" : "A", DataCoord[0], DataCoord[1], DataCoord[2], NewCoords2[0], NewCoords2[1], NewCoords2[2]));
new Class[32];
get_entvar(ent, var_classname, Class, charsmax(Class));
ArrayPushString(SaveClassname, Class);
NewCheck[id] = ent;
ArrayNum[id]++;
}
else
{
ArraySetString(NewSaveCoords, ArrayNum[id]-1, fmt("%s %f %f %f %f %f %f", Sign[id] == 1 ? "O" : "A", DataCoord[0], DataCoord[1], DataCoord[2], NewCoords2[0], NewCoords2[1], NewCoords2[2]));
}
}
ReadAndSaveCoordinate(bool:value)
{
new Path[MAX_RESOURCE_PATH_LENGTH];
get_localinfo("amxx_configsdir", Path, charsmax(Path));
new Map[MAX_MAPNAME_LENGTH];
get_mapname(Map, charsmax(Map));
formatex(Path, charsmax(Path), "%s/%s/ent_coords_%s.cfg", Path, PLUGIN_DIR, Map);
if(!value ? !file_exists(Path) : file_exists(Path))
{
if(!value)
{
set_fail_state("Error! no file: %s", Path);
return;
}
else
{
delete_file(Path);
}
}
switch(value)
{
case false:
{
new f = fopen(Path, "rt");
new Data[300], Type[2][6], classname[32], origin_x[2][13], origin_y[2][13], origin_z[2][13], angles_x[2][13], angles_y[2][13], angles_z[2][13];
while(!feof(f))
{
fgets(f, Data, charsmax(Data));
trim(Data);
if(!Data[0]) continue;
parse(Data, Type[0], charsmax(Type[]), classname, charsmax(classname), origin_x[0], charsmax(origin_x[]), origin_y[0], charsmax(origin_y[]), origin_z[0], charsmax(origin_z[]), angles_x[0], charsmax(angles_x[]), angles_y[0], charsmax(angles_y[]), angles_z[0], charsmax(angles_z[]), Type[1], charsmax(Type[]), origin_x[1], charsmax(origin_x[]), origin_y[1], charsmax(origin_y[]), origin_z[1], charsmax(origin_z[]), angles_x[1], charsmax(angles_x[]), angles_y[1], charsmax(angles_y[]), angles_z[1], charsmax(angles_z[]));
ArrayPushString(SaveClassname, classname);
ArrayPushString(OldSaveCoords, Type[0] == 'A' ? fmt("%s %s %s %s %s %s", origin_x[0], origin_y[0], origin_z[0], angles_x[0], angles_y[0], angles_z[0]) : fmt("%s %s %s %s %s %s", angles_x[0], angles_y[0], angles_z[0], origin_x[0], origin_y[0], origin_z[0]));
ArrayPushString(NewSaveCoords, Type[1] == 'A' ? fmt("%s %s %s %s %s %s", origin_x[1], origin_y[1], origin_z[1], angles_x[1], angles_y[1], angles_z[1]) : fmt("%s %s %s %s %s %s", angles_x[1], angles_y[1], angles_z[1], origin_x[1], origin_y[1], origin_z[1]));
ArrayPushString(Sign, Type);
}
fclose(f);
}
case true:
{
new i, Buff1[32], Buff2[128], Buff3[128];
while(i < ArraySize(SaveClassname))
{
Buff1[0] = EOS;
ArrayGetString(SaveClassname, i, Buff1, charsmax(Buff1));
Buff2[0] = EOS;
ArrayGetString(OldSaveCoords, i, Buff2, charsmax(Buff2));
Buff3[0] = EOS;
ArrayGetString(NewSaveCoords, i, Buff3, charsmax(Buff3));
write_file(Path, fmt("%s %s %s", Buff1, Buff2, Buff3));
}
}
}
}
SearchAndChangeOfPositions()
{
new i, Buff1[32], Buff2[128], Buff3[128], Buff4[6];
while(i < ArraySize(SaveClassname))
{
Buff1[0] = EOS;
ArrayGetString(SaveClassname, i, Buff1, charsmax(Buff1));
Buff2[0] = EOS;
ArrayGetString(OldSaveCoords, i, Buff2, charsmax(Buff2));
Buff3[0] = EOS;
ArrayGetString(NewSaveCoords, i, Buff3, charsmax(Buff3));
Buff4[0] = EOS;
ArrayGetString(Sign, i, Buff4, charsmax(Buff4));
OldEntityHandler(Buff1, Buff2, Buff3, Buff4);
}
}
OldEntityHandler(classname[], old_coords[], new_coords[], type[])
{
new StringCoords[6][13], Float:FloatOrigin[3], Float:FloatAngles[3];
parse(old_coords, StringCoords[0], charsmax(StringCoords[]), StringCoords[1], charsmax(StringCoords[]), StringCoords[2], charsmax(StringCoords[]), StringCoords[3], charsmax(StringCoords[]), StringCoords[4], charsmax(StringCoords[]), StringCoords[5], charsmax(StringCoords[]));
if()
{
}
else
{
}
FloatOrigin[0] = str_to_float(type[0] == 'A' ? StringCoords[0] : );
FloatOrigin[1] = str_to_float(StringCoords[1]);
FloatOrigin[2] = str_to_float(StringCoords[2]);
FloatAngles[0] = str_to_float(StringCoords[3]);
FloatAngles[1] = str_to_float(StringCoords[4]);
FloatAngles[2] = str_to_float(StringCoords[5]);
SearchHandler(false, classname, FloatCoords[0], FloatCoords[1], new_coords);
SearchHandler(true, classname, FloatCoords[0], FloatCoords[1], new_coords);
}
SearchHandler(bool:value, classname[], Float:old_coords1[3], Float:old_coords2[3], new_coords[])
{
new ent = -1;
while(ent = rg_find_ent_by_class(ent, classname, !value ? false : true))
{
new Float:Origin[3], Float:Angles[3];
get_entvar(ent, var_origin, Origin);
get_entvar(ent, var_angles, Angles);
if(!Sorting(old_coords1, old_coords2, Origin, Angles)) continue;
AssigningNewCoordinatesHandler(ent, new_coords);
}
}
bool:Sorting(Float:old_coords1[3], Float:old_coords2[3], Float:new_coords1[3], Float:new_coords2[3])
{
if(old_coords1[0] == new_coords1[0] && old_coords1[1] == new_coords1[1] && old_coords1[2] == new_coords1[2] && old_coords2[0] == new_coords2[0] && old_coords2[1] == new_coords2[1] && old_coords2[2] == new_coords2[2])
{
return true;
}
return false;
}
AssigningNewCoordinatesHandler(ent, new_coords[])
{
new StringCoords[6][13], Float:FloatCoords[2][3];
parse(new_coords, StringCoords[0], charsmax(StringCoords[]), StringCoords[1], charsmax(StringCoords[]), StringCoords[2], charsmax(StringCoords[]), StringCoords[3], charsmax(StringCoords[]), StringCoords[4], charsmax(StringCoords[]), StringCoords[5], charsmax(StringCoords[]));
FloatCoords[0][0] = str_to_float(StringCoords[0]);
FloatCoords[0][1] = str_to_float(StringCoords[1]);
FloatCoords[0][2] = str_to_float(StringCoords[2]);
FloatCoords[1][0] = str_to_float(StringCoords[3]);
FloatCoords[1][1] = str_to_float(StringCoords[4]);
FloatCoords[1][2] = str_to_float(StringCoords[5]);
new Float:Origin[3], Float:Angles[3];
get_entvar(ent, var_origin, Origin);
get_entvar(ent, var_angles, Angles);
}