p.s. если мало денег то определити цену попрашу народ на другом форуме - за такое скинутся
(ведь если исключить манор со скрипта то простенький скриптбот очень неплохо раскупят)
думаю даже Вороновски подошел бы тока достроить его до манора и тока на соло
(кчему лишнее) и растолковать по пунктам что надо делать...вот за это и хочу платить..
выкладываю более менее универсальный скрипт на баферов.. у вас ШЕ ПП БИШ ЕЕ?
впринципе независимо от сотава- скрипт переделок не требует.. запускаете и всё работет..
но! ваши пожелания в (когда и каму хилить и каким скилом ) учитываются там.. я коменты вставил- где править надо..
скрипт хорош тем что нетребует переделок если увас нет ШЕ ПП БИШ и ЕЕ одновременно а есть кто то 1..
етот скрипт исползует и баф и реген и хил.. для любого состава бафера точнее он написан для состава БИШ+ПП+ШЕ+ЕЕ- но подрузумевает в себе что их нет одновременно..
Код:
var
Bot1X,Bot1Y,Bot1Z,Bot2X,Bot2Y,Bot2Z,Bot3X,Bot3Y,Bot3Z,Bot4X,Bot4Y,Bot4Z:string; //координаты баферов
IDAssistTarget:string; //таргет командира
rnd:integer; // вспомогательная для случайного события
bafSE: array [1..100] of string; //список бафов ШЕ
bafPP: array [1..100] of string; //список бафов ПП
bafEE: array [1..100] of string; //список бафов ЕЕ
BafSEApplyChar: array [1..100] of string; //указывает ИД чара на которого нужно наложить баф с помощью ШЕ
BafSEApplyBaf: array [1..100] of string; //указывает какой баф наложить на чара с помощью ШЕ
BafPPApplyChar: array [1..100] of string; //указывает ИД чара на которого нужно наложить баф с помощью ПП
BafPPApplyBaf: array [1..100] of string; //указывает какой баф наложить на чара с помощью ПП
BafEEApplyChar: array [1..100] of string; //указывает ИД чара на которого нужно наложить баф с помощью ЕЕ
BafEEApplyBaf: array [1..100] of string; //указывает какой баф наложить на чара с помощью ЕЕ
NameKom,NameBot1,NameBot2,NameBot3,NameBot4:string; //имена чаров учавствующих в процессе
MaxHPKom,MaxHPBot1,MaxHPBot2,MaxHPBot3,MaxHPBot4:integer; //максимальные уровни ХП (лимиты)
MaxMPKom,MaxMPBot1,MaxMPBot2,MaxMPBot3,MaxMPBot4:integer; //максимальные уровни МП (лимиты)
//текущее значение ХП и МП
CurHPKom,CurMPKom,CurHPbot1,CurMPbot1,CurHPbot2,CurMPbot2,CurHPbot3,CurMPbot3,CurHPbot4,CurMPbot4:integer;
IDKomandos,IDbot1,IDbot2,IDbot3,IDbot4:string; // идешники всех
timer3: TTimer; //для создания пати
timer4: TTimer; //мульти-баф, общий как для физика так и для мага.. нужные бафы указываются заранее в конце скрипта
BufEndSE,BufEndPP,BufEndEE:boolean;// используется в таймере (мультибаф) для указания на то что 1 из баферов закончил бафать
tick3,tick4:integer; // используется в таймере бафа для тиков.. каждый тик- новый баф..
i:integer;
tempD:integer;
tempS:String;
//**********************МУЛЬТИБАФ***********************************************************
procedure OnTimer4(Sender: TObject);
begin
//если очередной баф в списке бафов для бафера = '' (окончание процесса бафа) то значит бафер уже отбафал всё что нужно, хватит бафать..
if (BafPPApplyChar[tick4]='') then BufEndPP:=True;
if (BafSEApplyChar[tick4]='') then BufEndSE:=True;
if (BafEEApplyChar[tick4]='') then BufEndEE:=True;
//если все баферы закончили бафать то выключаем таймер мультибафа
//ну и счетчик тиков ставим в исходное положение
if (BufEndPP=True) and (BufEndSE=True) and (BufEndEE=True) then
begin
tick4:=1;
timer4.enabled:=false;
BufEndSE:=False;
BufEndPP:=False;
BufEndEE:=False;
//раз закончили бафать то не допускаем выполнение нижеследущего кода
exit;
end;
//бафаем чара.. используется переменные BafPPApplyChar[tick4],BafPPApplyBaf[tick4] для ПП и аналогичные для ШЕ и ЕЕ указывающие на то какому баферу ково бафать и каким бафом в текущий ТИК.
//ТИК- (tick4) - ето счетчик, который изменяется на 1 с каждым новым бафом.. т.е. каждые 4 секунды (интервал таймера) тик увеличивается на 1
//ТИКИ нужны чтоб каждый раз новый баф кастовать..
buf:=hstr('04') + BafPPApplyChar[tick4] + Bot2X + Bot2Y + Bot2Z + hstr('00');
if (BufEndPP=False) and (IDbot2<>'') then SendToServerEX(NameBot2);
buf:=BafPPApplyBaf[tick4];
if (BufEndPP=False) and (IDbot2<>'') then SendToServerEX(NameBot2);
buf:=hstr('04') + BafSEApplyChar[tick4] + Bot3X + Bot3Y + Bot3Z + hstr('00');
if (BufEndSE=False) and (IDbot3<>'') then SendToServerEX(NameBot3);
buf:=BafSEApplyBaf[tick4];
if (BufEndSE=False) and (IDbot3<>'') then SendToServerEX(NameBot3);
buf:=hstr('04') + BafEEApplyChar[tick4] + Bot4X + Bot4Y + Bot4Z + hstr('00');
if (BufEndEE=False) and (IDbot4<>'') then SendToServerEX(NameBot4);
buf:=BafEEApplyBaf[tick4];
if (BufEndEE=False) and (IDbot4<>'') then SendToServerEX(NameBot4);
tick4:=tick4+1;
end;
//****************************РАЗДАЧА ПРИГЛАШЕНИЙ НА ВСТУПЛЕНИЕ В ПАТИ*******************
procedure OnTimer3(Sender: TObject);
begin
if tick3 = 1 then
begin
buf:=hstr('2B');
//этот код закоментирован , для того чтобы не разрывать пати.. впринципе хз каму как.. если надо четко стабиильно пати создать быстро из своих ботов-баферов то раскоментить
//а если ты с баферами + другие чары с тобой бегают- то ненадо раскоменчивать.. хотя можно тока баферов раскоментить тогда они свою пати порвут и снова вступят к командиру (если он лидер пати)
// if IDKomandos<>'' then SendToServerEX(NameKom);
// if IDBot1<>'' then SendToServerEX(NameBot1);
// if IDBot2<>'' then SendToServerEX(NameBot2);
// if IDBot3<>'' then SendToServerEX(NameBot3);
// if IDBot4<>'' then SendToServerEX(NameBot4);
end;
if tick3 = 2 then
begin
buf:=hstr('29');
writeS(namebot1);
buf:=buf + hstr('00 00 00 00');
SendToServerEX(NameKom);
end;
if tick3 = 3 then
begin
buf:=hstr('29');
writeS(namebot2);
buf:=buf + hstr('00 00 00 00');
SendToServerEX(NameKom);
end;
if tick3 = 4 then
begin
buf:=hstr('29');
writeS(namebot3);
buf:=buf + hstr('00 00 00 00');
SendToServerEX(NameKom);
end;
if tick3 = 5 then
begin
buf:=hstr('29');
writeS(namebot4);
buf:=buf + hstr('00 00 00 00');
SendToServerEX(NameKom);
end;
tick3:=tick3+1;
//ну когда всем баферам приглашение отправили то вырубаем таймер
if tick3=6 then
begin
tick3:=1;
timer3.enabled:=false;
end;
end;
//*************************БЕЖИМ ЗА ЛИДЕРОМ*******************************************
//процедура заставляет бежать ботов за лидером
procedure BotBeg;
begin
//проверяем условие чтоб координаты ботов небыли равными '' и ИД был перехвачен
if IDKomandos <> '' then
begin
//выделяем командира, эмулируя щелчек мыши
buf:=hstr('04') + IDKomandos + Bot1X + Bot1Y + Bot1Z + hstr('00');
if IDBot1<>'' then SendToServerEX(NameBot1);
//бежим за командиром эмулируя повторный щелчек мыши по таргету
buf:=hstr('04') + IDKomandos + Bot1X + Bot1Y + Bot1Z + hstr('00');
if IDBot1<>'' then SendToServerEX(NameBot1);
//выделяем командира, эмулируя щелчек мыши
buf:=hstr('04') + IDKomandos + Bot2X + Bot2Y + Bot2Z + hstr('00');
if IDBot2<>'' then SendToServerEX(NameBot2);
//бежим за командиром эмулируя повторный щелчек мыши по таргету
buf:=hstr('04') + IDKomandos + Bot2X + Bot2Y + Bot2Z + hstr('00');
if IDBot2<>'' then SendToServerEX(NameBot2);
//выделяем командира, эмулируя щелчек мыши
buf:=hstr('04') + IDKomandos + Bot3X + Bot3Y + Bot3Z + hstr('00');
if IDBot3<>'' then SendToServerEX(NameBot3);
//бежим за командиром эмулируя повторный щелчек мыши по таргету
buf:=hstr('04') + IDKomandos + Bot3X + Bot3Y + Bot3Z + hstr('00');
if IDBot3<>'' then SendToServerEX(NameBot3);
//выделяем командира, эмулируя щелчек мыши
buf:=hstr('04') + IDKomandos + Bot4X + Bot4Y + Bot4Z + hstr('00');
if IDBot4<>'' then SendToServerEX(NameBot4);
//бежим за командиром эмулируя повторный щелчек мыши по таргету
buf:=hstr('04') + IDKomandos + Bot4X + Bot4Y + Bot4Z + hstr('00');
if IDBot4<>'' then SendToServerEX(NameBot4);
end;
end;
procedure Init; //Вызывается при включении скрипта
begin
NameKom:='ИМЯ КОМАНДИРА';
NameBot1:='ИМЯ БИША'; //биш
NameBot2:='ИМЯ ПП'; //пп
NameBot3:='ИМЯ ШЕ'; //ше
NameBot4:='ИМЯ ЕЕ'; //ее
//список бафов:
bafPP[1]:=hstr('2F 0B 04 00 00 00 00 00 00 00'); // ментал
bafPP[2]:=hstr('2F 10 04 00 00 00 00 00 00 00'); // пд
bafPP[3]:=hstr('2F 2C 04 00 00 00 00 00 00 00'); // па
bafPP[4]:=hstr('2F 35 04 00 00 00 00 00 00 00'); // фокус
bafPP[5]:=hstr('2F 36 04 00 00 00 00 00 00 00'); // кон
bafPP[6]:=hstr('2F 3D 04 00 00 00 00 00 00 00'); // акумен
bafPP[7]:=hstr('2F A7 04 00 00 00 00 00 00 00'); // резист к огню
bafPP[8]:=hstr('2F B4 04 00 00 00 00 00 00 00'); // вв
bafPP[9]:=hstr('2F 26 04 00 00 00 00 00 00 00'); // берс
bafPP[10]:=hstr('2F 14 04 00 00 00 00 00 00 00'); // ХП реген
bafPP[12]:=hstr('2F 3E 04 00 00 00 00 00 00 00'); // хаст
bafPP[13]:=hstr('2F 15 04 00 00 00 00 00 00 00'); // блесс ХП
bafPP[14]:=hstr('2F 0C 04 00 00 00 00 00 00 00'); // маджик барьер
bafPP[15]:=hstr('2F 6C 05 00 00 00 00 00 00 00'); // гритер ПА
bafPP[16]:=hstr('2F 6D 05 00 00 00 00 00 00 00'); // гритер ПД
bafPP[17]:=hstr('2F 70 05 00 00 00 00 00 00 00'); // скаред атак резист
bafPP[18]:=hstr('2F 71 05 00 00 00 00 00 00 00'); // дарк атак резист
bafPP[19]:=hstr('2F A5 04 00 00 00 00 00 00 00'); // резист к ветру
bafPP[20]:=hstr('2F 9E 04 00 00 00 00 00 00 00'); // резист к воде
bafPP[21]:=hstr('2F DA 04 00 00 00 00 00 00 00'); // деф виспер
bafPP[22]:=hstr('2F D8 04 00 00 00 00 00 00 00'); // гвиданс
bafPP[23]:=hstr('2F 18 04 00 00 00 00 00 00 00'); // блесс МП
bafPP[24]:=hstr('2F DB 04 00 00 00 00 00 00 00'); // ЩИТ РЕЙТ
bafSE[1]:=hstr('2F 0B 04 00 00 00 00 00 00 00'); // ментал
bafSE[2]:=hstr('2F 10 04 00 00 00 00 00 00 00'); // ПД
bafSE[3]:=hstr('2F 2C 04 00 00 00 00 00 00 00'); // ПА
bafSE[4]:=hstr('2F F4 04 00 00 00 00 00 00 00'); // ВАМП
bafSE[5]:=hstr('2F 23 04 00 00 00 00 00 00 00'); // ЕМП
bafSE[6]:=hstr('2F 17 05 00 00 00 00 00 00 00'); // М.КРИТ
bafSE[7]:=hstr('2F 35 04 00 00 00 00 00 00 00'); // ФОКУС
bafSE[8]:=hstr('2F DA 04 00 00 00 00 00 00 00'); // ДЕФ ВИСПЕР
bafSE[9]:=hstr('2F D8 04 00 00 00 00 00 00 00'); // гвиданс
bafSE[10]:=hstr('2F B4 04 00 00 00 00 00 00 00'); // ВВ
bafEE[1]:=hstr('2F EB 04 00 00 00 00 00 00 00'); // резист ШОК
bafEE[2]:=hstr('2F 3F 04 00 00 00 00 00 00 00'); // ЭВЕЙШН
CurHPKom:=15000;
CurHPBot1:=15000;
CurHPBot2:=15000;
CurHPBot3:=15000;
CurHPBot4:=15000;
CurMPKom:=15000;
CurMPBot1:=15000;
CurMPBot2:=15000;
CurMPBot3:=15000;
CurMPBot4:=15000;
MaxHPKom:=10;
MaxHPBot1:=10;
MaxHPBot2:=10;
MaxHPBot3:=10;
MaxHPBot4:=10;
tick3:=1;
tick4:=1;
BufEndSE:=False;
BufEndPP:=False;
BufEndEE:=False;
timer4:=TTimer.Create(nil);
timer4.OnTimer:=@OnTimer4; //
timer4.enabled:=false; //
timer4.interval:=4000;
timer3:=TTimer.Create(nil);
timer3.OnTimer:=@OnTimer3; //
timer3.enabled:=false; //
timer3.interval:=1000;
// ЗАПРОС НА ОТКРЫТИЕ ИНВЕНТОРЯ!!!! ДЛЯ ЗАХВАТА ИДЕШНИКА!
// чтобы принудительно вызвать от сервера пакет ЮЗЕР ИНФО в котором ИД указан
buf:=hstr('0F');
SendToServerEX(NameKom);
SendToServerEX(NameBot1);
SendToServerEX(NameBot2);
SendToServerEX(NameBot3);
SendToServerEX(NameBot4);
end;
procedure Free; //Вызывается при выключении скрипта
begin
timer3.Free;
timer4.Free;
end;
//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin
//для тго чтоб 2-3 скрипта коректно работали одновременно..
if pck='' then exit;
//******************************АВТОСОГЛАШЕНИЕ НА ВСТУПЛЕНИЕ В ПАТИ************************
//******************************ПРИ УСЛОВИИ ЧТО ПАТИ ДАЕТ- КОМАНДИР************************
//ну тут тупо считываем имя кто нам шлет пати из пакета на предложение в него вступить
//ну и если имя- командир то вступаем в ету пати автоматом..
if FromServer then
if ConnectName=NameBot1 then
if pck[1]=#$39 then
if ReadS(2)=NameKom then
begin
buf:=hstr('2A 01 00 00 00');
sendtoserverex(NameBot1);
end;
if FromServer then
if ConnectName=NameBot2 then
if pck[1]=#$39 then
if ReadS(2)=NameKom then
begin
buf:=hstr('2A 01 00 00 00');
sendtoserverex(NameBot2);
end;
if FromServer then
if ConnectName=NameBot3 then
if pck[1]=#$39 then
if ReadS(2)=NameKom then
begin
buf:=hstr('2A 01 00 00 00');
sendtoserverex(NameBot3);
end;
if FromServer then
if ConnectName=NameBot4 then
if pck[1]=#$39 then
if ReadS(2)=NameKom then
begin
buf:=hstr('2A 01 00 00 00');
sendtoserverex(NameBot4);
end;
//*******************ЗАХВАТ КООРДИНАТ***************************************************
//если принят пакет от клиента с кординатами бота то
if FromClient then
if ConnectName=NameBot1 then
if pck[1]=#$48 then
begin
//запоминаем координаты
Bot1X:= pck[2] + pck[3] + pck[4] + pck[5];
Bot1Y:= pck[6] + pck[7] + pck[8] + pck[9];
Bot1Z:= pck[10] + pck[11] + pck[12] + pck[13];
end;
//если принят пакет от клиента с кординатами бота то
if FromClient then
if ConnectName=NameBot2 then
if pck[1]=#$48 then
begin
//запоминаем координаты
Bot2X:= pck[2] + pck[3] + pck[4] + pck[5];
Bot2Y:= pck[6] + pck[7] + pck[8] + pck[9];
Bot2Z:= pck[10] + pck[11] + pck[12] + pck[13];
end;
//если принят пакет от клиента с кординатами бота то
if FromClient then
if ConnectName=NameBot3 then
if pck[1]=#$48 then
begin
//запоминаем координаты
Bot3X:= pck[2] + pck[3] + pck[4] + pck[5];
Bot3Y:= pck[6] + pck[7] + pck[8] + pck[9];
Bot3Z:= pck[10] + pck[11] + pck[12] + pck[13];
end;
//если принят пакет от клиента с кординатами бота то
if FromClient then
if ConnectName=NameBot4 then
if pck[1]=#$48 then
begin
//запоминаем координаты
Bot4X:= pck[2] + pck[3] + pck[4] + pck[5];
Bot4Y:= pck[6] + pck[7] + pck[8] + pck[9];
Bot4Z:= pck[10] + pck[11] + pck[12] + pck[13];
end;
//********************ОСТСЛЕЖИВАЕМ ТРУПАКИ********************************************************
//если кто то умер то приходит пакет DIE.. то хилить его ненадо...
//нефиг трупы хилить...
//для того чтоб трупяков боты не хилили ставим кодом то что ХП (текущее) у них до жопы... т.е. 15к
if FromServer then
if ConnectName=NameKom then
if pck[1]=#$06 then
if pck[2] + pck[3] + pck[4] + pck[5] = IDKomandos then
CurHPKom:=15000;
if FromServer then
if ConnectName=NameBot1 then
if pck[1]=#$06 then
if pck[2] + pck[3] + pck[4] + pck[5] = IDBot1 then
CurHPBot1:=15000;
if FromServer then
if ConnectName=NameBot2 then
if pck[1]=#$06 then
if pck[2] + pck[3] + pck[4] + pck[5] = IDBot2 then
CurHPBot2:=15000;
if FromServer then
if ConnectName=NameBot3 then
if pck[1]=#$06 then
if pck[2] + pck[3] + pck[4] + pck[5] = IDBot3 then
CurHPBot3:=15000;
if FromServer then
if ConnectName=NameBot4 then
if pck[1]=#$06 then
if pck[2] + pck[3] + pck[4] + pck[5] = IDBot3 then
CurHPBot4:=15000;
//*************************УЗНАЕМ ЛИМИТЫ ХП и МП и ИД***********************************************
//из пакета UserInfo который приходит во время бафа и не только
//как тока скрипт начинает свою работу то он на все аки отправляет запрос на открытие ИНВЕНТОРЯ
//вместе с ответом сервера всегда приходит пакет ЮЗЕР ИНФО.. из етого замечательного пакета мы считываем максимальные значения ХП и МП
//а так жэ ИД чара (бота- бафера)
//КОМАНДИР
if FromServer then
if ConnectName = NameKom then
if pck[1]=#$04 then
begin
IDKomandos:=pck[18]+pck[19]+pck[20]+pck[21]; //тут выдергиваем ИД чара
i:=22;
tempS:=readS(i); // ето используем для удобства.. имя типа пропускаем.. потому как каждый раз оно из разного кол-ва букв состоит.. в скобках переменная автоматом увеличивается на кол-во букв (ну там по формуле.. в юникоде 1 буква=2 байта, и символ окончания строки еще 00 00)
i:=i+48; // через 48 байтофъ после имени указывается лимиты и текущие значения для ХП и МП
//запоминаем их.. тут нам не особо важны текущие значения.. хотя лишний раз не помешают
//но важно- максимальное значение- ЛИМИТЫ
MaxHPKom:=readD(i);
CurHPKOM:=readD(i);
MaxMPKom:=readD(i);
CurMPKOM:=readD(i);
end;
//1-й бот
if FromServer then
if ConnectName = NameBot1 then
if pck[1]=#$04 then
begin
IDBot1:=pck[18]+pck[19]+pck[20]+pck[21];
i:=22;
tempS:=readS(i);
i:=i+48;
MaxHPBot1:=readD(i);
CurHPBot1:=readD(i);
MaxMPBot1:=readD(i);
CurMPBot1:=readD(i);
end;
//2-й бот
if FromServer then
if ConnectName = NameBot2 then
if pck[1]=#$04 then
begin
IDBot2:=pck[18]+pck[19]+pck[20]+pck[21];
i:=22;
tempS:=readS(i);
i:=i+48;
MaxHPBot2:=readD(i);
CurHPBot2:=readD(i);
MaxMPBot2:=readD(i);
CurMPBot2:=readD(i);
end;
//3-й бот
if FromServer then
if ConnectName = NameBot3 then
if pck[1]=#$04 then
begin
IDBot3:=pck[18]+pck[19]+pck[20]+pck[21];
i:=22;
tempS:=readS(i);
i:=i+48;
MaxHPBot3:=readD(i);
CurHPBot3:=readD(i);
MaxMPBot3:=readD(i);
CurMPBot3:=readD(i);
end;
//4-й бот
if FromServer then
if ConnectName = NameBot4 then
if pck[1]=#$04 then
begin
IDBot4:=pck[18]+pck[19]+pck[20]+pck[21];
i:=22;
tempS:=readS(i);
i:=i+48;
MaxHPBot4:=readD(i);
CurHPBot4:=readD(i);
MaxMPBot4:=readD(i);
CurMPBot4:=readD(i);
end;
//*************************СЛЕДИМ ЗА ХП и МП******************************************
//а ету часть кода требуется под ваши жэлания настроить..
//тут указываются значения при которых ПП ШШ ЕЕ БИШ будут вам ману лить и ХП заливать и каким именно скилом
//следим за ХП КОМАНДИРА
//отлавливаем СТАТУС АПДЕЙТ!!!!!
//как выяснилось статус апдейта бывает 2 разных..
//1 для ХП, 2 для МП
//етот пакет приходит при любом изменении ХП и МП у чара..
//чтоб их отличить сервак использует индекс.. в 6-м байте присылает либо 4 либо 2..
//если в 6-м байте СТАТУС АПДЕЙТ цифра #$04 то значит реч в етом пакете про ХП
//а если #$02 то реч в етом пакете про МП..
//возможно что для ЦП есть еще другой указатель но скрипт не учитывает ЦП никак..
if FromServer then
if ConnectName = NameKom then
if pck[1]=#$0e then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDKomandos + #$04) then
begin
//считываем текущее состояние ХП!!-)
CurHPKom:=ReadD(14);
//ну собственно ето уже можно править под желания каждого:
//если жизни текущие меньше 0,7 от шкалы (70%) и при етом больше (0,25 = 25%)25% от шкалы то..
//то биш использует свой любимый скил МАЖОР ХИЛ за спирит оре (в интерлюде) (для ц4 такого скила нету)
if (CurHPKom < round(MaxHPKom*0.7)) and (CurHPKom > round(MaxHPKom*0.25)) then
begin
buf:=hstr('04') + IDKomandos + Bot1X + Bot1Y + Bot1Z + hstr('00');
if (IDBot1 <> '') then SendToServerEX(NameBot1);
buf:=hstr('2F 79 05 00 00 00 00 00 00 00'); // МАЖОР ХИЛ
if (IDBot1 <> '') then SendToServerEX(NameBot1);
end;
//если жизни опустились меньше чем 25% то надо хилить бишем очень быстро поетому используем БЕТЛ ХИЛ
//(чтоб из жопы вытащить)
if (CurHPKom < round(MaxHPKom*0.2)) then
begin
buf:=hstr('04') + IDKomandos + Bot1X + Bot1Y + Bot1Z + hstr('00');
if (IDBot1 <> '') then SendToServerEX(NameBot1);
buf:=hstr('2F C2 04 00 00 00 00 00 00 00'); // БЭТЛ ХИЛ
if (IDBot1 <> '') then SendToServerEX(NameBot1);
end;
// при желании можно еще чтоб ПП хилил.. лимит при котором он будет хилить БЕТЛ ХИЛОМ устанавливаем..
if (CurHPKom < round(MaxHPKom*0.7)) then
begin
buf:=hstr('04') + IDKomandos + Bot2X + Bot2Y + Bot2Z + hstr('00');
if (IDBot2 <> '') then SendToServerEX(NameBot2);
buf:=hstr('2F F7 03 00 00 00 00 00 00 00'); //ПП ХИЛИТ
if (IDBot2 <> '') then SendToServerEX(NameBot2);
end;
//ШЕ НЕ ХИЛИТ но вставивив сюда 6 строк аналогичных предыдущим будет и ШЕ хилить..
//но зато хилит ЕЕ.. смотрите.. аналогично может и ШЕ хилить...
//вы уже поняли что ЕЕ включит хил на 50% ХП командира
if (CurHPKom < round(MaxHPKom*0.5)) then
begin
buf:=hstr('04') + IDKomandos + Bot4X + Bot4Y + Bot4Z + hstr('00');
if (IDBot4 <> '') then SendToServerEX(NameBot4);
buf:=hstr('2F C1 04 00 00 00 00 00 00 00 '); //ЕЕ ХИЛИТ
if (IDBot4 <> '') then SendToServerEX(NameBot4);
end;
end;
//следим за ХП у БОТ1
//если злой хренко решит наших баферов бить, а потом нас- то мы просто так не сдадимся..
//баферам ХИЛ дадим.. чтоб хренко били били и не убили...
//я сделал тупо- чтоб тока сам себя хилял бафер.. добавьте аналогичные строки сюда и будет так что все баферы будут хилить баф-бота
//ето надо полюбасу- но пока руки не дошли.. и вам немного задачи- доделать скрипт..
//но я етого не сделал еще по одной причине.. в реальных условиях мой командир бегает оч шустро..
//баферы отстают.. если 1 бафер на пвп отстанет- да и хер с ним.. а если етого отстающего бьют..
//и все мои баферы кинутся его хилить (если его бьют) то я через 15 сек буду оч далеко и меня уже баферы не догонят
//и я буду- (командир пати) без хила.. поетому если бафера атакуют то я сделал чтоб он сам себя лечил..
// но чтоб другие не лечили, чтоб другие за мной бежали..
if FromServer then
if ConnectName = NameBot1 then
if pck[1]=#$0e then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDbot1 + #$04) then
begin
CurHPbot1:=ReadD(14);
//на 70% шкалы хилит бафер сам себя (бишоп) скилом мажор хил
if (CurHPbot1 < round(MaxHPBot1*0.7)) then
begin
buf:=hstr('04') + IDbot1 + Bot1X + Bot1Y + Bot1Z + hstr('00');
if (IDBot1 <> '') then SendToServerEX(NameBot1);
buf:=hstr('2F 79 05 00 00 00 00 00 00 00'); //скил бишопа: можор хил
if (IDBot1 <> '') then SendToServerEX(NameBot1);
end;
end;
//следим за ХП у БОТ2
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameBot2 then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDbot2 + #$04) then
begin
CurHPbot2:=ReadD(14);
if (CurHPbot2 < round(MaxHPBot2*0.7)) then
begin
buf:=hstr('04') + IDbot2 + Bot1X + Bot1Y + Bot1Z + hstr('00');
if (IDBot1 <> '') and (IDBot2 <> '') then SendToServerEX(NameBot1);
buf:=hstr('2F 79 05 00 00 00 00 00 00 00');
if (IDBot1 <> '') and (IDBot2 <> '') then SendToServerEX(NameBot1);
end;
end;
//следим за ХП у БОТ3
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameBot3 then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDbot3 + #$04) then
begin
CurHPbot3:=ReadD(14);
if (CurHPbot3 < round(MaxHPBot3*0.7)) then
begin
buf:=hstr('04') + IDbot3 + Bot3X + Bot3Y + Bot3Z + hstr('00');
if (IDBot3 <> '') then SendToServerEX(NameBot3);
buf:=hstr('2F C1 04 00 00 00 00 00 00 00');
if (IDBot3 <> '') then SendToServerEX(NameBot1);
end;
end;
//следим за ХП у БОТ4
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameBot4 then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDbot4 + #$04) then
begin
CurHPbot4:=ReadD(14);
if (CurHPbot4 < round(MaxHPBot4*0.7)) then
begin
buf:=hstr('04') + IDbot4 + Bot4X + Bot4Y + Bot4Z + hstr('00');
if (IDBot4 <> '') and (IDBot4 <> '') then SendToServerEX(NameBot4);
buf:=hstr('2F C1 04 00 00 00 00 00 00 00');
if (IDBot4 <> '') then SendToServerEX(NameBot4);
end;
end;
//следим за МП у КОМАНДИРА (ШЕ следит)
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameKom then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDKomandos + #$02) then
begin
CurMPkom:=ReadD(14);
if (CurMPkom < round(MaxMPkom*0.5)) then
begin
buf:=hstr('04') + IDKomandos + Bot3X + Bot3Y + Bot3Z + hstr('00');
if (IDBot3 <> '') then SendToServerEX(NameBot3);
buf:=hstr('2F F5 03 00 00 00 00 00 00 00');
if (IDBot3 <> '') then SendToServerEX(NameBot3);
end;
end;
//следим за МП у КОМАНДИРА (ЕЕ следит)
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameKom then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDKomandos + #$02) then
begin
CurMPkom:=ReadD(14);
if (CurMPkom < round(MaxMPkom*0.5)) then
begin
buf:=hstr('04') + IDKomandos + Bot4X + Bot4Y + Bot4Z + hstr('00');
if (IDBot4 <> '') then SendToServerEX(NameBot4);
buf:=hstr('2F F5 03 00 00 00 00 00 00 00');
if (IDBot4 <> '') then SendToServerEX(NameBot4);
end;
end;
//следим за МП у БИША
//этот кусок кода вполне альтернативный..
if FromServer then
if pck[1]=#$0e then
if ConnectName = NameBot1 then
if (pck[2] + pck[3] + pck[4] + pck[5] + pck[6] = IDbot1 + #$02) then
begin
CurMPBot1:=ReadD(14);
if (CurMPBot1 < round(MaxMPBot1*0.9)) then
begin
buf:=hstr('04') + IDBot1 + Bot3X + Bot3Y + Bot3Z + hstr('00');
if (IDBot3 <> '') then SendToServerEX(NameBot3);
buf:=hstr('2F F5 03 00 00 00 00 00 00 00');
if (IDBot3 <> '') then SendToServerEX(NameBot3);
end;
end;
//**********************СЛЕДИМ ЗА ТАРГЕТАМИ****************************************
//КОМАНДИР
//если принят пакет со сменой таргета у командира то
if FromServer then
if ConnectName = NameKom then
if pck[1]=#$A6 then
begin
//запоминаем ИД таргета командира для ассиста
IDAssistTarget:= pck[2]+pck[3]+pck[4]+pck[5];
end;
//**********************САЖАЕМ ВСЮ ПАТИ ЧЕРЕЗ КОНТРОЛ****************************************
//если принят пакет на сажание с контролом то сажаем всю пати
if FromClient then
if (ConnectName = NameKom) then
if (pck[1]+pck[2]+pck[6]=hstr('45 00 01')) then
begin
buf:=hstr('45 00 00 00 00 01 00 00 00 00');
if IDBot1<>'' then SendToServerEX(NameBot1);
if IDBot2<>'' then SendToServerEX(NameBot2);
if IDBot3<>'' then SendToServerEX(NameBot3);
if IDBot4<>'' then SendToServerEX(NameBot4);
end;
//*******************БЕЖИМ ЗА КОМАНДИРОМ ПОСЛЕ ИСПОЛЬЗОВАНИЯ СКИЛА***************************
//ловим пакет МАДЖИКСКИЛЮЗ
if FromServer then
if pck[1] = #$48 then
if (pck[2]+pck[3]+pck[4]+pck[5]=IDBOT1) or (pck[2]+pck[3]+pck[4]+pck[5]=IDBOT2) or (pck[2]+pck[3]+pck[4]+pck[5]=IDBOT3) then
begin
BotBeg;
end;
//**************************УПРАВЛЕНИЕ************************************************
//"Bow" (ПОКЛОН)- БЕЖАТЬ за КОМАНДИРОМ
if FromClient then
if ConnectName=NameKom then
if pck[1]+pck[2]=hstr('1B 07') then
begin
pck:='';
BotBeg;
exit;
end;
//ADVANCE- В АТАКУ - пати быстрое создание (3-я кнопка)
if FromClient then
if ConnectName=NameKom then
if pck[1]+pck[2]=hstr('1B 04') then
begin
pck:='';
//сразу рвем пати у всех чаров и командир раздает пати поновому
//чары автоматически принимают пати
//используется таймер т.к. одновременно 2-м чарам пати кинуть нельзя
timer3.enabled:=true;
exit;
end;
//YES- РУТ ПО АССИСТУ (4-я кнопка) либо переделать в какойто дебаф от каждого бафера он свой.. по ассисту все баферы какуюто куйню кинут на цель по ассисту..
if FromClient then
if ConnectName=NameKom then
if pck[1]+pck[2]=hstr('1B 06') then
begin
pck:='';
buf:=hstr('04') + IDAssistTarget + Bot1X + Bot1Y + Bot1Z + hstr('00');
if NameBot1<>'' then SendToServerEX(NameBot1);
buf:=hstr('04') + IDAssistTarget + Bot2X + Bot2Y + Bot2Z + hstr('00');
if NameBot2<>'' then SendToServerEX(NameBot2);
buf:=hstr('04') + IDAssistTarget + Bot3X + Bot3Y + Bot3Z + hstr('00');
if NameBot3<>'' then SendToServerEX(NameBot3);
buf:=hstr('2F 72 05 00 00 01 00 00 00 00');
if NameBot1<>'' then SendToServerEX(NameBot1);
buf:=hstr('2F B1 04 00 00 01 00 00 00 00');
if NameBot2<>'' then SendToServerEX(NameBot2);
buf:=hstr('2F B1 04 00 00 00 00 00 00 00');
if NameBot3<>'' then SendToServerEX(NameBot3);
exit;
end;
//NO буф МАГА по ассисту
if FromClient then
if ConnectName=NameKom then
if pck[1]+pck[2]=hstr('1B 05') then
begin
BafPPApplyChar[1]:=IDAssistTarget;
BafPPApplyBaf[1]:=bafPP[1];
BafPPApplyChar[2]:=IDAssistTarget;
BafPPApplyBaf[2]:=bafPP[2];
BafPPApplyChar[3]:=IDAssistTarget;
BafPPApplyBaf[3]:=bafPP[5];
BafPPApplyChar[4]:=IDAssistTarget;
BafPPApplyBaf[4]:=bafPP[6];
BafPPApplyChar[5]:=IDAssistTarget;
BafPPApplyBaf[5]:=bafPP[7];
BafPPApplyChar[6]:=IDAssistTarget;
BafPPApplyBaf[6]:=bafPP[8];
BafPPApplyChar[7]:=IDAssistTarget;
BafPPApplyBaf[7]:=bafPP[9];
BafPPApplyChar[8]:=IDAssistTarget;
BafPPApplyBaf[8]:=bafPP[23];
BafPPApplyChar[9]:=IDAssistTarget;
BafPPApplyBaf[9]:=bafPP[13];
BafPPApplyChar[10]:=IDAssistTarget;
BafPPApplyBaf[10]:=bafPP[14];
BafPPApplyChar[11]:=IDAssistTarget;
BafPPApplyBaf[11]:=bafPP[16];
BafPPApplyChar[12]:=IDAssistTarget;
BafPPApplyBaf[12]:=bafPP[18];
BafPPApplyChar[13]:=IDAssistTarget;
BafPPApplyBaf[13]:=bafPP[19];
BafPPApplyChar[14]:=IDAssistTarget;
BafPPApplyBaf[14]:=bafPP[20];
BafPPApplyChar[15]:='';
BafPPApplyBaf[15]:='';
BafSEApplyChar[1]:=IDAssistTarget;
BafSEApplyBaf[1]:=bafSE[5];
BafSEApplyChar[2]:=IDAssistTarget;
BafSEApplyBaf[2]:=bafSE[6];
BafSEApplyChar[3]:='';
BafSEApplyBaf[3]:='';
BafEEApplyChar[1]:=IDAssistTarget;
BafEEApplyBaf[1]:=bafEE[1];
BafEEApplyChar[2]:=IDAssistTarget;
BafEEApplyBaf[2]:=bafEE[2];
BafEEApplyChar[3]:='';
BafEEApplyBaf[3]:='';
timer4.enabled:=true;
pck:='';
exit;
end;
//UNAWARE буф ФИЗИКА по ассисту
if FromClient then
if ConnectName=NameKom then
if pck[1]+pck[2]=hstr('1B 08') then
begin
BafPPApplyChar[1]:=IDAssistTarget;
BafPPApplyBaf[1]:=bafPP[1];
BafPPApplyChar[2]:=IDAssistTarget;
BafPPApplyBaf[2]:=bafPP[2];
BafPPApplyChar[3]:=IDAssistTarget;
BafPPApplyBaf[3]:=bafPP[3];
BafPPApplyChar[4]:=IDAssistTarget;
BafPPApplyBaf[4]:=bafPP[4];
BafPPApplyChar[5]:=IDAssistTarget;
BafPPApplyBaf[5]:=bafPP[7];
BafPPApplyChar[6]:=IDAssistTarget;
BafPPApplyBaf[6]:=bafPP[8];
BafPPApplyChar[7]:=IDAssistTarget;
BafPPApplyBaf[7]:=bafPP[9];
BafPPApplyChar[8]:=IDAssistTarget;
BafPPApplyBaf[8]:=bafPP[22];
BafPPApplyChar[9]:=IDAssistTarget;
BafPPApplyBaf[9]:=bafPP[12];
BafPPApplyChar[10]:=IDAssistTarget;
BafPPApplyBaf[10]:=bafPP[13];
BafPPApplyChar[11]:=IDAssistTarget;
BafPPApplyBaf[11]:=bafPP[14];
BafPPApplyChar[12]:=IDAssistTarget;
BafPPApplyBaf[12]:=bafPP[15];
BafPPApplyChar[13]:=IDAssistTarget;
BafPPApplyBaf[13]:=bafPP[18];
BafPPApplyChar[14]:=IDAssistTarget;
BafPPApplyBaf[14]:=bafPP[19];
BafPPApplyChar[15]:=IDAssistTarget;
BafPPApplyBaf[15]:=bafPP[20];
BafPPApplyChar[16]:=IDAssistTarget;
BafPPApplyBaf[16]:=bafPP[21];
BafPPApplyChar[17]:='';
BafPPApplyBaf[17]:='';
BafSEApplyChar[1]:=IDAssistTarget;
BafSEApplyBaf[1]:=bafSE[4];
BafSEApplyChar[2]:='';
BafSEApplyBaf[2]:='';
BafEEApplyChar[1]:=IDAssistTarget;
BafEEApplyBaf[1]:=bafEE[1];
BafEEApplyChar[2]:=IDAssistTarget;
BafEEApplyBaf[2]:=bafEE[2];
BafEEApplyChar[3]:='';
BafEEApplyBaf[3]:='';
timer4.enabled:=true;
pck:='';
exit;
end;
end.
__________________
Цитата:
Сообщение от pybukon
прежде чета попросить я немнога раскажу чтоб вы понили как мне плоха
Цитата:
Сообщение от Byrger
А как сделать мой скрипт бесконечным?
Цитата:
Сообщение от XKOR
.. каждый день ионизированной ногой протирает больную)
Цитата:
Сообщение от PsyR
Вылоджите пожалуйста скрипт на рыбалку желательно что бы сам в ВХ клал адаптированый под шоки и так же скрипт на ТТ рец, тоже с диалогами
Достоинства:
- миникарта;
- панель с инфой;
- бафает себя:
- юзает кубики;
- юзает пошин алакрити;
- лечит себя хил пошинами и элементал хилом;
Код:
//Bot by Skymanrus
//modified by NLObP специально для Владера, моего сына!
//***************************************************************
const
name='NLObP'; //имя чара для которого включен скрипт
//установить константу в зависимости от типа игры (С4 или Интерлюд)
IL=false; //true - IL, false - C4
max=50; //максимальное значение массива
buff1=91; //бафф defense aura
buff2=77; //бафф attack aura
buff3=112; //бафф deflect arrow
buff4=230; //бафф sprint
buff5=123; //бафф spirit barrier
cubicstorm=10;
cubiclife=67;
elementalheal=58;
//***************************************************************
var
info, msg, stats : TMemo;
frm : TForm;
map : Tform; //виртуальная карта
offs1, xm, ym : integer;
heal, kill : string;
MaxHP, MyZpos, cvaZ, CurHP, ID, xpos, ypos, skill, MyID, PercentHP, MEsit: integer;
MEup, but, sud, bst, Radius, cvaX, attackIDMinID, attackk, attackID, cvaY, zpos: integer;
Hpotion, Apotion, MyXpos, MyYpos, rezu, MaxX, MaxID, MinID, MinX: integer;
sit, povtor, tame, gdo, npc : Boolean;
bfi, atck, hpi, i, ii: integer;
last : integer; //последняя запись в массиве, для ускорения скрипта
MobsID: array[1..max] of integer;
MobsRAS: array[1..max] of integer;
MobsX: array[1..max] of integer;
MobsY: array[1..max] of integer;
MobsZ: array[1..max] of integer;
NPCid: array[1..max] of integer;
Aggro: array[1..max] of Boolean;
Shape: array [0..max] of Tshape; //виртуальная карта
timer1: TTimer;
timer2: TTimer;
timer3: TTimer;
//***************************************************************
procedure Init; //УПРАВЛЯЮЩИЕ ПЕРЕМЕННЫЕ
var
i: integer;
begin
if il then begin
//CharInfo
offs1:=48; //44 для С4, 48 для IL
end else begin
offs1:=44;
end;
atck:=0; //кол-во неуспешных атак после которых пробуем сместиться
hpi:=0;
bfi:=60; //60 сек, чтобы бафы не пропустить
ii:=1;
last:=1; //начальное значение
Radius:=1500; // радиус круга кача! Можно под место править.
PercentHP:=70; // при каком количестве хп в % юзать бутылку лечения
MEsit:=55; // при каком количестве хп в % надо сесть и подкопить хп
MEup:=90; // при каком количестве хп в % надо встать после отдыха
frm := TForm.Create(nil);
frm.Caption := 'BOT '+name;
frm.BorderStyle := bsSizeable;
frm.Position := poScreenCenter;
frm.Width:=520;
frm.Height:=700;
info:=TMemo.Create(frm);
info.parent:=frm;
info.align:=alLeft;
info.ReadOnly:=true;
info.ScrollBars:=0;
info.Width:=470;
info.Height:=370;
info.Lines.Add('БОТ НЕ ПОДКЛЮЧЁН К СЕРВЕРУ!');
msg:=TMemo.Create(frm);
msg.parent:=frm;
msg.align:=alBottom;
msg.ReadOnly:=true;
msg.ScrollBars:=0;
msg.Width:=570;
msg.Height:=100;
msg.Lines.Add('...');
stats:=TMemo.Create(frm);
stats.parent:=frm;
stats.align:=alRight;
stats.ReadOnly:=true;
stats.ScrollBars:=0;
stats.Width:=140;
stats.Height:=100;
frm.Show;
map := TForm.Create(nil);
map.Caption := 'MiniMap: '+name;
map.BorderStyle := bsSizeable;
map.Position := poScreencenter;
map.Width:=300;
map.Height:=300;
map.FormStyle:=FsStayOnTop;
map.Show;
heal:=HStr('45 00 00 00 00 00 00 00 00 00 '); // СИДЕТЬ!!!
//атака и прочее
timer1:=TTimer.Create(nil);
timer1.OnTimer:=@OnTimer1; //
timer1.enabled:=false; // таймер по умолчанию выключен
timer1.interval:=1000; // через каждые 1сек будем обновлять
//вывод в форму
timer2:=TTimer.Create(nil);
timer2.OnTimer:=@OnTimer2; //
timer2.enabled:=true; // таймер по умолчанию включен
timer2.interval:=1000; // через каждые 1сек будем обновлять
//баффы
timer3:=TTimer.Create(nil);
timer3.OnTimer:=@OnTimer3; //
timer3.enabled:=true; // таймер по умолчанию выключен
timer3.interval:=60000; // первый баф через 60 сек
for i:= 1 to max do begin
Aggro[i]:=false;
Shape[i]:=Tshape.create(nil); //для мобов
Shape[i].parent:=map;
Shape[i].Brush.Color:=clGreen; //(clBlack, clRed, clGreen, clYellow, clBlue, clPurple)
Shape[i].left:=-7; //координаты
Shape[i].top:=-7;
Shape[i].width:=7; //размеры
Shape[i].height:=7;
end;
shape[0]:=Tshape.create(nil); //для моего чара
shape[0].parent:=map;
//shape[0].Brush.Color:= clBlack ;
shape[0].left:=-5; //координаты
shape[0].top:=-5;
shape[0].width:=5; //размеры
shape[0].height:=5;
end;
//***************************************************************
procedure GameToMap(x, y : integer);
//преобразуем игровые координаты в координаты карты
//никак не сделаю нормальные преобразования =(
var
masshtabx, masshtaby : extended;
begin
masshtabx:=radius*2/map.Width;
masshtaby:=radius*2/map.Height;
xm:=Round((x-cvaX+map.Width/2)/masshtabx); //координата X на карте
ym:=Round((y-cvaY+map.Height/2)/masshtaby); //координата Y на карте
end;
//***************************************************************
procedure ViewInfo;
var
i: integer;
begin
info.Lines.Clear;
stats.Lines.Clear;
stats.Lines.Add('MaxHP :'+IntToStr(MaxHP));
stats.Lines.Add('CurHP :'+IntToStr(CurHP));
stats.Lines.Add('MyID :'+IntToStr(MyID));
stats.Lines.Add('MyXpos :'+IntToStr(MyXpos));
stats.Lines.Add('MyYpos :'+IntToStr(MyYpos));
stats.Lines.Add('MyZpos :'+IntToStr(MyZpos));
stats.Lines.Add('Radius :'+IntToStr(RADIUS));
stats.Lines.Add('cvaX :'+IntToStr(cvaX));
stats.Lines.Add('cvaY :'+IntToStr(cvaY));
stats.Lines.Add('cvaZ :'+IntToStr(cvaZ));
stats.Lines.Add('skill :'+IntToStr(skill)+' юзал скил');
stats.Lines.Add('but :'+IntToStr(but)+' бутылки');
stats.Lines.Add('sud :'+IntToStr(sud)+' сидеть');
stats.Lines.Add('bst :'+IntToStr(bst)+' встать');
stats.Lines.Add('ID :'+IntToStr(ID)+' кто ходит');
stats.Lines.Add('xpos :'+IntToStr(xpos)+' кто ходит');
stats.Lines.Add('ypos :'+IntToStr(ypos)+' кто ходит');
stats.Lines.Add('zpos :'+IntToStr(zpos)+' кто ходит');
stats.Lines.Add('sit :'+VarToStr(sit));
stats.Lines.Add('PercentHP :'+IntToStr(PercentHP)+' %хп');
stats.Lines.Add('MEsit :'+IntToStr(MEsit)+' %хп');
stats.Lines.Add('MEup :'+IntToStr(MEup)+' %хп');
stats.Lines.Add('attackIDMinID :'+IntToStr(attackIDMinID)+' ближний');
stats.Lines.Add('attackID :'+IntToStr(attackID)+' ближний');
stats.Lines.Add('attackk :'+IntToStr(attackk)+' цикл атак');
stats.Lines.Add('atck :'+IntToStr(atck)+' цикл неудачных атак');
stats.Lines.Add('Last :'+IntToStr(Last)+' последняя в бд');
stats.Lines.Add('SummaAR :'+IntToStr(Summ(MobsID))+' всего в бд');
stats.Lines.Add('rezu :'+IntToStr(delta(MyXpos, MyYpos, xpos, ypos))+' рез ближ');
stats.Lines.Add('MaxX :'+IntToStr(MaxX));
stats.Lines.Add('MaxID :'+IntToStr(MaxID));
stats.Lines.Add('MinX :'+IntToStr(MinX));
stats.Lines.Add('MinID :'+IntToStr(MinID));
stats.Lines.Add('povtor :'+VarToStr(povtor));
stats.Lines.Add('tame :'+VarToStr(tame)+' выч %хп');
stats.Lines.Add('gdo :'+VarToStr(gdo)+' центр окр');
stats.Lines.Add('Hpotion: '+inttostr(Hpotion));
stats.Lines.Add('Apotion: '+inttostr(Apotion));
// if (MaxHP<>0) then begin
info.Lines.Add('Ближайший МОБ: id='+IntToStr(MinID)+' дистанция='+IntToStr(MinX));
info.Lines.Add('HP:'+IntToStr(CurHP)+' из '+IntToStr(MaxHP)+' Цикл1='+IntToStr(attackk)+' Цикл2='+IntToStr(atck)+' Цикл бафа='+IntToStr(bfi));
if (Hpotion=0) then info.Lines.Add('Юзать HP бутылки?: НЕТ!');
if (Hpotion<>0) then info.Lines.Add('Юзать HP бутылки?: ДА!');
if (Apotion=0) then info.Lines.Add('Юзать AP бутылки?: НЕТ!');
if (Apotion<>0) then info.Lines.Add('Юзать AP бутылки?: ДА!');
if (sit=false) then info.Lines.Add('Бот стоит!');
if (sit=true) then info.Lines.Add('Бот сидит!');
for i:= 1 to last do begin
if (MobsID[i]<>0) then begin
if (attackIDMinID<>i) then info.Lines.Add('--'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
if (attackIDMinID=i) then info.Lines.Add('->'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
end;
end;
for i:= 1 to last do begin
if (MobsID[i]<>0) then begin
GameToMap(MobsX[i],MobsY[i]);
Shape[i].left:=xm; //координаты моба
Shape[i].top:=ym;
if Aggro[i]=true then Shape[i].Brush.Color:=clPurple;
end;
end;
// end;
if (MaxHP=0) then info.Lines.Add(' Для инициализации Бота используй аптечку!');
end;
//***************************************************************
procedure Free;
begin
DelALL;
end;
//***************************************************************
procedure StatsUpdate;
var
i: integer;
begin
for i:=0 to ReadD(6)-1 do begin
case pck[i*8+10] of
#$09: CurHP:=ReadD(i*8+14);
#$0A: MaxHP:=ReadD(i*8+14);
end;
end;
if (MaxHP<>0) then // вычисляем процентное соотношение хп
begin
but:=Round((MaxHP/100)*PercentHP); // при каком количестве хп юзать бутылку лечения
sud:=Round((MaxHP/100)*MEsit); // при каком количестве хп надо сесть и подкопить хп
bst:=Round((MaxHP/100)*MEup); // при каком количестве хп надо встать после отдыха
end;
end;
//***************************************************************
//ПЕРЕМЕЩЕНИЕ:
//Идти в точку с координатами x,y,z
//MOVETO(x,y,z)
procedure MoveTo(TargetX,TargetY,TargetZ:integer);
begin
//01=MoveBackwardToLocation:d(targetX)d(targetY)d(targetZ)d(originX)d(originY)d(originZ)d(moveByMouse)
buf:=#$01;
WriteD(targetx); //куда
WriteD(targety);
WriteD(targetz);
WriteD(MyXpos); //откуда
WriteD(MyYpos);
WriteD(MyZpos);
WriteD(1); //используем 1-мышь 0-клавиатура
SendToServerEx(Name);
msg.Lines.Add('MoveTo('+inttostr(targetx)+','+inttostr(targety)+','+inttostr(targetz)+')');
end;
//***************************************************************
//Ориентация на местности:
//Проверка находится ли заданная точка в пределах досягаемости. Если да, то выполняется кусок скрипта в фигурных скобках {}.
function PosInRange(targetx,targety,targetz,distanciya:extended):boolean;
begin
if delta(targetx, targety, MyXpos, MyYpos)<=distanciya
then result:=true else result:=false;
end;
//***************************************************************
function delta(xpos1, ypos1, xpos2, ypos2:extended):integer; //возвращает переменную rezu которая является растоянием между 2 точками
begin
result:= Round(Sqrt(((xpos1-xpos2)*(xpos1-xpos2))+((ypos1-ypos2)*(ypos1-ypos2))));
end;
//***************************************************************
procedure DelElArr(ele:integer); //удаляет моба!
begin
MobsID[ele]:=0;
MobsRAS[ele]:=0;
MobsX[ele]:=0;
MobsY[ele]:=0;
MobsZ[ele]:=0;
Aggro[ele]:=false;
Shape[ele].left:=-7; //координаты, чтобы небыло видно на карте
Shape[ele].top:=-7;
Shape[i].Brush.Color:=clGreen;
end;
//***************************************************************
procedure DelALL; //обнуляем всю базу!
var
i: integer;
begin
for i:= 1 to max do begin
NPCid[i]:=0;
MobsID[i]:=0;
MobsRAS[i]:=0;
MobsX[i]:=0;
MobsY[i]:=0;
MobsZ[i]:=0;
Aggro[i]:=false;
shape[i].free;
end;
shape[0].free;
timer1.Free;
timer2.Free;
timer3.Free;
info.Free;
msg.Free;
frm.Free;
map.Free;
end;
//***************************************************************
procedure GetMinMaxX(arra:array of integer);
//возвращает в переменную MinX - мин и MaxX - макс значение массива, а в MinID, MaxID номер этого элемента
var
i: integer;
begin
MinX:=5000;
MinID:=0;
MaxX:=0;
MaxID:=0;
for i:= 1 to last do begin
if (arra[i]<=MinX) and (arra[i]<>0) then begin
MinX:=arra[i];
MinID:=i;
end;
if (arra[i]>=MaxX) then begin
MaxX:=arra[i];
MaxID:=i;
end;
end;
end;
//***************************************************************
function ETOpovtor(chislo: integer; arra:array of integer):boolean;
//возвращает переменную povtor и если она равна 1 значит chislo уже есть в массиве!
var
i: integer;
begin
Result:=false;
for i:= 1 to last do begin
if (arra[i]=chislo) then Result:=true;
end;
end;
//***************************************************************
procedure attackt(mobus:integer);
begin
buf:=#$04; //action
WriteD(MobsID[mobus]);
WriteD(MyXpos);
WriteD(MyYpos);
WriteD(MyZpos);
WriteC(0);
SendToServerEx(Name);
end;
//***************************************************************
function Summ(sum:array of integer):integer;
//возвращает переменную SummaAR с количеством полных(не пустых) ячеек
var
Summa: integer;
i: integer;
begin
Result:=0;
for i:= 1 to max do begin
if (sum[i]<>0) then inc(Result);
end;
end;
//***************************************************************
procedure OnTimer1(Sender: TObject); //ВЫДЕЛЕНИЕ И АТАКА МОБА!!!!!!!!!!!!!
begin
//не всегда атакует по двойному клику, поэтому клики с задержкой в 1 сек.
//повторяем через 6 сек. двойной клик
if (MinID>0) then begin
if (sit=false) then begin
case attackk of
0: begin
msg.Lines.Add('Атакую! '+IntToStr(ID));
attackID:=MobsID[MinID];
attackIDMinID:=MinID;
attackt(attackIDMinID); //target
end;
//делаем паузу
1: begin
attackt(attackIDMinID); //attack
end;
6: begin
attackt(attackIDMinID); //target
end;
//делаем паузу
7: begin
attackt(attackIDMinID); //attack
attackk:=-1;
inc(atck);
end;
end;
//если стоим 35 сек ((attackk=7)*5), убираем текущий таргет и пробуем другой, вдруг поможет =)
case atck of
5: begin
MobsRAS[attackIDMinID]:=5000;
// GetMinMaxX(MobsRAS);
attackk:=-1;
atck:=0;
end;
end;
inc(attackk);
end;
end;
end;
//***************************************************************
procedure OnTimer2(Sender: TObject); //
begin
//контролируем бафы, если время бафов, то пытаемся бафаться каждую секунду
dec(bfi);
if bfi<0 then begin
timer3.interval:=1000; //каждые 1 сек
bfi:=1200; //20 мин
end;
//выводим в форму
ViewInfo;
GetMinMaxX(MobsRAS);
if (Summ(MobsRAS)>=round(max*0.9)) or (MaxX>5000) then begin
//если у нас занято более 90% ячеек с мобами надо удалить самых дальних от нас
msg.Lines.Add('мусор удалён:'+IntToStr(MaxID)+' :'+IntToStr(MaxX)+' сумма'+IntToStr(Summ(MobsRAS))+'-');
DelElArr(MaxID);
end;
//идем в центр если нет мобов. Это можно включить при желании,
//только будет мешать при управлении мобом
{
if (Summ(MobsRAS)=0) and (timer1.enabled=true) and (cvax<>0) then begin
if not PosInRange(cvaX,cvaY,cvaZ,50) then MoveTo(cvaX,cvaY,cvaZ);
end;
}
//лечимся в промежутках между битвами
if (CurHP<but) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add('Баффаюсь elemental heal!');
MagicSkillUse(elementalheal);
end;
//лечимся бутылками все время
if (CurHP<but) and (Hpotion<>0) then begin
if hpi=5 then begin
UseItem(Hpotion);
hpi:=0;
end else inc(hpi);
end;
//сидим если надо
if (CurHP<sud) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add(' все блин я отдыхаю!');
buf:=heal;
SendToServerEx(Name);
sit:=true;
end;
//встаем
if (CurHP>bst) and (sit=true) then begin
msg.Lines.Add(' пора за работу!');
buf:=heal;
SendToServerEx(Name);
attackk:=0;
atck:=0;
sit:=false;
end;
end;
//***************************************************************
procedure OnTimer3(Sender: TObject); //баффы
begin
//если никого не бъем, то надо бафаться
if (Summ(Aggro)=0) and (sit=false) then begin
case ii of
1: begin
timer1.enabled:=false; //откл. атаку
msg.Lines.Add('Баффаюсь Defense aura!');
//бафф
MagicSkillUse(buff1);
inc(ii);
timer3.interval:=6000; //каждые 6 сек
end;
2: begin
msg.Lines.Add('Баффаюсь Attack aura!');
MagicSkillUse(buff2);
inc(ii);
end;
3: begin
msg.Lines.Add('Баффаюсь Deflect arrow!');
MagicSkillUse(buff3);
inc(ii);
end;
4: begin
msg.Lines.Add('Баффаюсь Sprint!');
MagicSkillUse(buff4);
inc(ii);
end;
5: begin
msg.Lines.Add('Баффаюсь Spirit barrier!');
MagicSkillUse(buff5);
inc(ii);
timer3.interval:=10000; //каждые 10 сек
end;
6: begin
msg.Lines.Add('Баффаюсь Storm cubic!');
MagicSkillUse(cubicstorm);
inc(ii);
end;
7: begin
msg.Lines.Add('Баффаюсь Life cubic!');
MagicSkillUse(cubiclife);
inc(ii);
end;
8: begin
if Hpotion<>0 then begin
msg.Lines.Add('Potion of Alacrity!');
UseItem(Apotion);
end;
inc(ii);
end;
9: begin
ii:=1;
timer3.interval:=1150000; //каждые 20 мин
bfi:=1150;
timer1.enabled:=true; //вкл. атаку
end;
end;
end;
end;
//***************************************************************
procedure AddBD(id, posx, posy, posz:integer;); //добавляем моба в базу данных
var
i: integer;
begin
for i:=1 to last do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(id, MobsID)=false) then begin
MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsID[i])+'-ras-'+IntToStr(MobsRAS[i]));
GameToMap(posx,posy);
shape[i].left:=xm; //координаты моба
shape[i].top:=ym;
break;
end;
end;
end;
//если нет свободного места ищем дальше
for i:=last+1 to max do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(id, MobsID)=false) then begin
MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsID[i])+'-ras-'+IntToStr(MobsRAS[i]));
last:=i;
GameToMap(posx,posy);
shape[i].left:=xm; //координаты моба
shape[i].top:=ym;
break;
end;
end;
end;
end;
//***************************************************************
function ISnpc(id: integer;): boolean;
var
i: integer;
begin
result:=false;
for i:= 1 to max do if (NPCid[i]=id) then result:=true;
end;
//***************************************************************
procedure UseItem(ObjID:integer);
begin
buf:=#$14;
WriteD(ObjID);
WriteD(00);
SendToServerEx(Name);
end;
//***************************************************************
//2F=RequestMagicSkillUse:dMagicID)d(CtrlPressed)b(ShiftPressed)
procedure MagicSkillUse(MagicID:integer);
begin
buf:=#$2F;
WriteD(MagicID);
WriteD(00);
WriteC(00);
SendToServerEx(Name);
end;
//******************************************************************************
// вызывается при приходе каждого пакета, если скрипт включен
//******************************************************************************
begin
//****************************************************************************
//не обрабатываем пустые пакеты
if pck='' then exit;
//****************************************************************************
if (ConnectName=Name) and FromServer then begin
case pck[1] of
#$76: begin
msg.Lines.Add('S>C $76');
if (ReadD(2)=MyID) then begin //я юзнул какой то скилл
msg.Lines.Add(' юзнул скилл!');
skill:=1;
end;
end;
#$0E: begin
msg.Lines.Add('S>C $0E StatsUpdate');
if (MyID=ReadD(2)) then StatsUpdate; //обновление информации о хп
end;
//MagicSkillUse 48, Attack 05
#$05: begin
msg.Lines.Add('S>C $05 Attack');
if (ReadD(6)=MyID) then begin
//меня ударили
sit:=false;
if (ETOpovtor(ReadD(2),MobsID)=false) then AddBD(ReadD(2),ReadD(15),ReadD(19),ReadD(23));
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin //если моб записан в базе данных
msg.Lines.Add('На нас напали враги!!!'+IntToStr(i)+'-'+IntToStr(attackIDMinID));
MobsRAS[i]:=1;
Aggro[i]:=true; // стал агрессор
if (timer1.enabled=false) then begin //если я только зашел в игру и на меня напали
attackIDMinID:=i;
timer1.enabled:=true;
end;
if (attackIDMinID<>0) and (Aggro[attackIDMinID]=false) then attackIDMinID:=i;
break;
end;
end;
end;
end;
#$0C: begin
msg.Lines.Add('S>C $0C DropItem');
if (MyXpos<>0) then begin
if (delta(MyXpos, MyYpos, ReadD(14), ReadD(18))<=200) then begin
msg.Lines.Add('Выпала вещь!!!');
timer1.enabled:=false;
buf:=#$04;
WriteD(ReadD(6));
WriteD(ReadD(14));
WriteD(ReadD(18));
WriteD(ReadD(22));
WriteC(0);
SendToServerEx(Name);
msg.Lines.Add(' Пробую поднять!!!');
delay(1000);
timer1.enabled:=true;
end;
end;
end;
#$04: begin
msg.Lines.Add('S>C $04 CharInfo');
//пакет с инфой о моём чаре
i:=2;
MyXpos:=ReadD(i); //получаю координату х моего чара
MyYpos:=ReadD(i); //получаю координату у моего чара
MyZpos:=ReadD(i); //получаю координату z моего чара
GameToMap(MyXpos,MyYpos);
shape[0].left:=xm; //координаты моего чара
shape[0].top:=ym;
//Запоминаем ИД
i:=18;
MyID:=ReadD(i); //получаю ид моего чара
//смещение переменное, зависит от имени (LenName*2+2)
i:=i+(Length(Name)*2+2)+offs1; //44 для С4, 48 для IL
MaxHP:=ReadD(i);
CurHP:=ReadD(i);
if (gdo=false) then begin //задаем центр окружности кача
cvaX:=MyXpos;
cvaY:=MyYpos;
gdo:=true;
end;
end;
#$01: begin
msg.Lines.Add('S>C $01 Move');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если кто-то перемещается
i:=2;
ID:=ReadD(i); //кто-то рыпнулся с места надо это записать...
xpos:=ReadD(i);
ypos:=ReadD(i);
zpos:=ReadD(i);
if not ISnpc(ID) and (delta(cvaX,cvaY,xpos,ypos)<=Radius) then AddBD(ID,xpos,ypos,zpos);
end;
end;
//принят пакет Die
#$06: begin
msg.Lines.Add('S>C $06 Die');
//моб сдох! выкидываем его из базы and (attackID=ReadD(2))
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin
DelElArr(i);
attackk:=0;
atck:=0;
msg.Lines.Add('БОБИК СДОХ!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
//принят пакет DeleteObject
#$12: begin
msg.Lines.Add('S>C $12 DeleteObject');
//выкидываем из базы
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin
DelElArr(i);
msg.Lines.Add('Удаляю из базы!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
#$03: begin
msg.Lines.Add('S>C $03 Char');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(18),NPCid)=false) then begin
NPCid[i]:=ReadD(18);
msg.Lines.Add('ИГРОК ДОБАВЛЕН!-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
#$16: begin
msg.Lines.Add('S>C $16 NPC');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
msg.Lines.Add('Вижу NPC!');
if (ReadD(10)=0) then begin //если нельзя атаковать
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(2), NPCid)=false) then begin
NPCid[i]:=ReadD(2);
msg.Lines.Add('Запомнили, NPCid='+IntToStr(ReadD(2))+' нельзя атаковать!');
break;
end;
end;
end;
end;
if (ReadD(10)=1) and (pck[120]=#$00) then begin //если можно атаковать
if (delta(cvaX, cvaY, ReadD(14), ReadD(18))<=RADIUS) then begin
AddBD(ReadD(2), ReadD(14), ReadD(18), ReadD(22));
msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' запомнили в базе!');
end
else msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' вне радиуса действия!');
end;
end;
end;
//InventoryUpdate
#$27: begin
msg.Lines.Add('S>C $27 InventoryUpdate');
if ((ReadD(12)=1060) or (ReadD(12)=1061)) then begin //Healing Potion, Lesser Healing Potion
Hpotion:=ReadD(8);
msg.Lines.Add('ID бутылок Hpotion:'+inttostr(Hpotion));
end;
if ReadD(12)=735 then begin //Potion of Alacrity
Apotion:=ReadD(8);
msg.Lines.Add('ID бутылок Apotion:'+inttostr(Apotion));
end;
end;
end;
end;
//****************************************************************************
if (ConnectName=Name) and FromClient then begin
case pck[1] of
#$1B: begin
msg.Lines.Add('C>S $1B ');
case ReadD(2) of
//социальное действие Yes для начала
$06: begin
cvaX:=MyXpos;
cvaY:=MyYpos;
cvaZ:=MyZpos;
attackk:=0;
atck:=0;
msg.Lines.Add('БОТ ВКЛЮЧЕН, координаты ОБНОВЛЕНЫ!!');
// GetMinMaxX(MobsRAS);
timer1.enabled:=true;
timer3.enabled:=true;
end;
//социальное действие No для окончания
$05: begin
timer1.enabled:=false;
timer3.enabled:=false;
msg.Lines.Add('БОТ ВЫКЛЮЧЕН!!!');
end;
{ //социальное действие Applaud
$0B: begin
if timer2.enabled=false
then timer2.enabled:=true
else timer2.enabled:=false;
attackk:=0;
atck:=0;
msg.Lines.Add('! ВКЛ/ВЫКЛ!!!');
end;
} //социальное действие Sorrow - удаляем текущую запись в базе
$0D: begin
ID:=MobsID[attackIDMinID];
DelElArr(attackIDMinID);
attackk:=0;
atck:=0;
msg.Lines.Add('Удаляем текущую запись в базе!!!');
for i:= last to max do begin
if (NPCid[i]=0) then begin
NPCid[i]:=ID;
msg.Lines.Add('ИГРОК ДОБАВЛЕН!-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
//ValidatePosition пакет от клиента с моими кординатами
#$48: begin
msg.Lines.Add('C>S $48 ValidatePosition');
//обновляем ВСЕ растояния в BD если мы сошли с места
MyXpos:=ReadD(2); //получаю координату х моего чара
MyYpos:=ReadD(6); //получаю координату у моего чара
MyZpos:=ReadD(10); //получаю координату z моего чара
GameToMap(MyXpos,MyYpos);
shape[0].left:=xm; //координаты моего чара
shape[0].top:=ym;
for i:=1 to last do begin
if (MobsID[i]<>0) then begin
if (true<>Aggro[i]) then begin
MobsRAS[i]:=delta(MyXpos,MyYpos,MobsX[i],MobsY[i]);
end;
end;
end;
end;
end;
end;
end.
да.. скажу вам честно- "ЛЁД ТРОНУЛСЯ- ГОСПОДА ПРИСЯЖНЫЕ!" .. а то на месте буксовали-)
NLObP:=+1
надо вникнуть протестить.. если не лень добавь еще коментов плиз.. некоторые куски при беглом осмотре непонятны.. чтоб не вникая в код было понятно как ето всё пашет.. если не трудно плиз сделай и закрепим тогда к первому посту.. хотя и в таком варианте тожэ прикрепим но хочется еще более доступный вид.. -)
пока не проверял в работе но вижу работа огромная проделана-) даже миникарта создана-)) супер.. и лог действий-)..
можно какнить обощить всех физиков в 1 скрипт? чтоб было несколько строк тока для переделки.. чтоб скрипт улавливал какието параметры (ХП,МП,состояние атаки, скока противников нас бьют одновременно) и от в зависимости от них инициализировался запуск процедуру- в теле которой что хатим то сами под себя и напишем, под каждую профу.. ну например: мало ХП, нас атакуют сразу 3= запускаем процедуру, в теле которой ТАНКИ- пропишут себе УД, СПЕЛСИНГЕР- пропишет ФЛЕШ- массовый что все убежали, ну чета такое например бы сделать.. хотя в любом случае твой скрипт надо брать за основу.. и доделывать уж его под жэлания каждого.. то что выкладывал я давным давно конечножэ в сравнение не идет с етим-)..
также в идеале, в качестве готового решения, надо сделать 2 скрипта 1 из которых управляет баферами, второй- мозг- управляет командиром.. впринципе сыровато пока но уже есть то что будет работать.. то что я выложил для баферов- неможет автоматом перебафывать командира.. но добавив 5 строк (в управляющий блок кода , в конце скрипта) можно заставить скрипт реагировать и выполнять ребаф по каманде в приват сообщение, присланное от бота- командира типа твоего.. вот ето будет савсем уж весело тогда-).. чтоб командир следил- каму и что делать в какихто неординарных случаях приказывал ботам неординарные приказы..-) а боты- баферы чтоб в своём скрипте неукаснительно их выполняли-)..
спасибо еще раз-) буду изучать терь то что ты напрогал..
__________________
Цитата:
Сообщение от pybukon
прежде чета попросить я немнога раскажу чтоб вы понили как мне плоха
Цитата:
Сообщение от Byrger
А как сделать мой скрипт бесконечным?
Цитата:
Сообщение от XKOR
.. каждый день ионизированной ногой протирает больную)
Цитата:
Сообщение от PsyR
Вылоджите пожалуйста скрипт на рыбалку желательно что бы сам в ВХ клал адаптированый под шоки и так же скрипт на ТТ рец, тоже с диалогами
при беглом просмотре понял что львиная часть скрипта это панельки и карты, которые я не как не могу понять ктонить популярно логику отображения в окошке может объяснить? :) а в целом за пару дней можно переделать для сумонера :) блага логика простая тока надо проверку добавить на хп сумона и проверку кто кого атакует + ко всему этому задержку между атакой сумона и сомонером ну что б сумонер первым не атакавал.
NLObP, поставь плиз побольше коментариев :oops: плизз, а то очень трудно понять что куда и откуда т.к. некоторые переменые я так и не нашёл где забиваются :( не сочти дебилом меня, но за 3 часа я не понял откуда взялся центр зоны кача %)
За основу взят бот из темы ОТПТИМИЗАЦИЯ БОТА! от skymanrus. Мне там особенно понравилась панель с инфой. До этого я все сообщения по отладке в чать кидал. С панелью намного удобнее отлаживать скрипт.
Панель состои из трех частей. Слева информация по базе мобов и атаках на них (стрелкой указывается цель). Справа информация о переменных. Снизу лог сообщений. Первым делом исправляем имя чара (в 3.1.8. выскакивала ошибка, в 3.2.0 ошибка не выскакивает и можно долго непонимать почему скрипт не работает). Включаем скрипт (через 1 мин включаются бафы). Пьем бутылкы Хил и Алакрити пошин. Можно не пить, тогда в скрипте не используются. Ставим нужный радиус: Radius:=1500; // радиус круга кача! Идем на место кача, жмем YES, вот код:
Код:
//социальное действие Yes для начала
$06: begin
cvaX:=MyXpos; //запоминаем центр кача
cvaY:=MyYpos;
cvaZ:=MyZpos;
attackk:=0; //
atck:=0;
msg.Lines.Add('БОТ ВКЛЮЧЕН, координаты ОБНОВЛЕНЫ!!');
timer1.enabled:=true; //включаем охоту на мобов
timer3.enabled:=true; //включаем работу бафов
end;
Бот готов к работе. Он видит мобов после того как они начнут двигаться или респавнящихся, неподвижных не видит. Ближайшего начинает атаковать. Если в базу попал NPC или рейд босс его можно принудительно убрать из списка - соц.действием Sorrow.
NLObP, поставь плиз побольше коментариев :oops: плизз, а то очень трудно понять что куда и откуда т.к. некоторые переменые я так и не нашёл где забиваются :( не сочти дебилом меня, но за 3 часа я не понял откуда взялся центр зоны кача %)
За основу взят бот из темы ОТПТИМИЗАЦИЯ БОТА! от skymanrus. Мне там особенно понравилась панель с инфой. До этого я все сообщения по отладке в чать кидал. С панелью намного удобнее отлаживать скрипт.
Панель состои из трех частей. Слева информация по базе мобов и атаках на них (стрелкой указывается цель). Справа информация о переменных. Снизу лог сообщений. Первым делом исправляем имя чара (в 3.1.8. выскакивала ошибка, в 3.2.0 ошибка не выскакивает и можно долго непонимать почему скрипт не работает). Включаем скрипт (через 1 мин включаются бафы). Пьем бутылкы Хил и Алакрити пошин. Можно не пить, тогда в скрипте не используются. Ставим нужный радиус: Radius:=1500; // радиус круга кача! Идем на место кача, жмем YES, вот код:
Код:
//социальное действие Yes для начала
$06: begin
cvaX:=MyXpos; //запоминаем центр кача
cvaY:=MyYpos;
cvaZ:=MyZpos;
attackk:=0; //
atck:=0;
msg.Lines.Add('БОТ ВКЛЮЧЕН, координаты ОБНОВЛЕНЫ!!');
timer1.enabled:=true; //включаем охоту на мобов
timer3.enabled:=true; //включаем работу бафов
end;
Бот готов к работе. Он видит мобов после того как они начнут двигаться или респавнящихся, неподвижных не видит. Ближайшего начинает атаковать. Если в базу попал NPC или рейд босс его можно принудительно убрать из списка - соц.действием Sorrow.
спс помог очень прям :) терь переделаю думаю... :) и выложу свой вариант, но уже как мне кажется более верный зона кача 4-х угольник, скрипт работает всегда для того что б можно было хотя б убежать подальше возрат в точку ребафа, постараюсь что б он делал это не приводя парик, но пока слабо представляю как это сделать, начну с зоны там увидим
Достоинства:
- миникарта;
- панель с инфой;
- бафает себя:
- юзает кубики;
- юзает пошин алакрити;
- лечит себя хил пошинами и элементал хилом;
Код:
//Bot by Skymanrus
//modified by NLObP специально для Владера, моего сына!
//***************************************************************
const
name='NLObP'; //имя чара для которого включен скрипт
//установить константу в зависимости от типа игры (С4 или Интерлюд)
IL=false; //true - IL, false - C4
max=50; //максимальное значение массива
buff1=91; //бафф defense aura
buff2=77; //бафф attack aura
buff3=112; //бафф deflect arrow
buff4=230; //бафф sprint
buff5=123; //бафф spirit barrier
cubicstorm=10;
cubiclife=67;
elementalheal=58;
//***************************************************************
var
info, msg, stats : TMemo;
frm : TForm;
map : Tform; //виртуальная карта
offs1, xm, ym : integer;
heal, kill : string;
MaxHP, MyZpos, cvaZ, CurHP, ID, xpos, ypos, skill, MyID, PercentHP, MEsit: integer;
MEup, but, sud, bst, Radius, cvaX, attackIDMinID, attackk, attackID, cvaY, zpos: integer;
Hpotion, Apotion, MyXpos, MyYpos, rezu, MaxX, MaxID, MinID, MinX: integer;
sit, povtor, tame, gdo, npc : Boolean;
bfi, atck, hpi, i, ii: integer;
last : integer; //последняя запись в массиве, для ускорения скрипта
MobsID: array[1..max] of integer;
MobsRAS: array[1..max] of integer;
MobsX: array[1..max] of integer;
MobsY: array[1..max] of integer;
MobsZ: array[1..max] of integer;
NPCid: array[1..max] of integer;
Aggro: array[1..max] of Boolean;
Shape: array [0..max] of Tshape; //виртуальная карта
timer1: TTimer;
timer2: TTimer;
timer3: TTimer;
//***************************************************************
procedure Init; //УПРАВЛЯЮЩИЕ ПЕРЕМЕННЫЕ
var
i: integer;
begin
if il then begin
//CharInfo
offs1:=48; //44 для С4, 48 для IL
end else begin
offs1:=44;
end;
atck:=0; //кол-во неуспешных атак после которых пробуем сместиться
hpi:=0;
bfi:=60; //60 сек, чтобы бафы не пропустить
ii:=1;
last:=1; //начальное значение
Radius:=1500; // радиус круга кача! Можно под место править.
PercentHP:=70; // при каком количестве хп в % юзать бутылку лечения
MEsit:=55; // при каком количестве хп в % надо сесть и подкопить хп
MEup:=90; // при каком количестве хп в % надо встать после отдыха
frm := TForm.Create(nil);
frm.Caption := 'BOT '+name;
frm.BorderStyle := bsSizeable;
frm.Position := poScreenCenter;
frm.Width:=520;
frm.Height:=700;
info:=TMemo.Create(frm);
info.parent:=frm;
info.align:=alLeft;
info.ReadOnly:=true;
info.ScrollBars:=0;
info.Width:=470;
info.Height:=370;
info.Lines.Add('БОТ НЕ ПОДКЛЮЧЁН К СЕРВЕРУ!');
msg:=TMemo.Create(frm);
msg.parent:=frm;
msg.align:=alBottom;
msg.ReadOnly:=true;
msg.ScrollBars:=0;
msg.Width:=570;
msg.Height:=100;
msg.Lines.Add('...');
stats:=TMemo.Create(frm);
stats.parent:=frm;
stats.align:=alRight;
stats.ReadOnly:=true;
stats.ScrollBars:=0;
stats.Width:=140;
stats.Height:=100;
frm.Show;
map := TForm.Create(nil);
map.Caption := 'MiniMap: '+name;
map.BorderStyle := bsSizeable;
map.Position := poScreencenter;
map.Width:=300;
map.Height:=300;
map.FormStyle:=FsStayOnTop;
map.Show;
heal:=HStr('45 00 00 00 00 00 00 00 00 00 '); // СИДЕТЬ!!!
//атака и прочее
timer1:=TTimer.Create(nil);
timer1.OnTimer:=@OnTimer1; //
timer1.enabled:=false; // таймер по умолчанию выключен
timer1.interval:=1000; // через каждые 1сек будем обновлять
//вывод в форму
timer2:=TTimer.Create(nil);
timer2.OnTimer:=@OnTimer2; //
timer2.enabled:=true; // таймер по умолчанию включен
timer2.interval:=1000; // через каждые 1сек будем обновлять
//баффы
timer3:=TTimer.Create(nil);
timer3.OnTimer:=@OnTimer3; //
timer3.enabled:=true; // таймер по умолчанию выключен
timer3.interval:=60000; // первый баф через 60 сек
for i:= 1 to max do begin
Aggro[i]:=false;
Shape[i]:=Tshape.create(nil); //для мобов
Shape[i].parent:=map;
Shape[i].Brush.Color:=clGreen; //(clBlack, clRed, clGreen, clYellow, clBlue, clPurple)
Shape[i].left:=-7; //координаты
Shape[i].top:=-7;
Shape[i].width:=7; //размеры
Shape[i].height:=7;
end;
shape[0]:=Tshape.create(nil); //для моего чара
shape[0].parent:=map;
//shape[0].Brush.Color:= clBlack ;
shape[0].left:=-5; //координаты
shape[0].top:=-5;
shape[0].width:=5; //размеры
shape[0].height:=5;
end;
//***************************************************************
procedure GameToMap(x, y : integer);
//преобразуем игровые координаты в координаты карты
//никак не сделаю нормальные преобразования =(
var
masshtabx, masshtaby : extended;
begin
masshtabx:=radius*2/map.Width;
masshtaby:=radius*2/map.Height;
xm:=Round((x-cvaX+map.Width/2)/masshtabx); //координата X на карте
ym:=Round((y-cvaY+map.Height/2)/masshtaby); //координата Y на карте
end;
//***************************************************************
procedure ViewInfo;
var
i: integer;
begin
info.Lines.Clear;
stats.Lines.Clear;
stats.Lines.Add('MaxHP :'+IntToStr(MaxHP));
stats.Lines.Add('CurHP :'+IntToStr(CurHP));
stats.Lines.Add('MyID :'+IntToStr(MyID));
stats.Lines.Add('MyXpos :'+IntToStr(MyXpos));
stats.Lines.Add('MyYpos :'+IntToStr(MyYpos));
stats.Lines.Add('MyZpos :'+IntToStr(MyZpos));
stats.Lines.Add('Radius :'+IntToStr(RADIUS));
stats.Lines.Add('cvaX :'+IntToStr(cvaX));
stats.Lines.Add('cvaY :'+IntToStr(cvaY));
stats.Lines.Add('cvaZ :'+IntToStr(cvaZ));
stats.Lines.Add('skill :'+IntToStr(skill)+' юзал скил');
stats.Lines.Add('but :'+IntToStr(but)+' бутылки');
stats.Lines.Add('sud :'+IntToStr(sud)+' сидеть');
stats.Lines.Add('bst :'+IntToStr(bst)+' встать');
stats.Lines.Add('ID :'+IntToStr(ID)+' кто ходит');
stats.Lines.Add('xpos :'+IntToStr(xpos)+' кто ходит');
stats.Lines.Add('ypos :'+IntToStr(ypos)+' кто ходит');
stats.Lines.Add('zpos :'+IntToStr(zpos)+' кто ходит');
stats.Lines.Add('sit :'+VarToStr(sit));
stats.Lines.Add('PercentHP :'+IntToStr(PercentHP)+' %хп');
stats.Lines.Add('MEsit :'+IntToStr(MEsit)+' %хп');
stats.Lines.Add('MEup :'+IntToStr(MEup)+' %хп');
stats.Lines.Add('attackIDMinID :'+IntToStr(attackIDMinID)+' ближний');
stats.Lines.Add('attackID :'+IntToStr(attackID)+' ближний');
stats.Lines.Add('attackk :'+IntToStr(attackk)+' цикл атак');
stats.Lines.Add('atck :'+IntToStr(atck)+' цикл неудачных атак');
stats.Lines.Add('Last :'+IntToStr(Last)+' последняя в бд');
stats.Lines.Add('SummaAR :'+IntToStr(Summ(MobsID))+' всего в бд');
stats.Lines.Add('rezu :'+IntToStr(delta(MyXpos, MyYpos, xpos, ypos))+' рез ближ');
stats.Lines.Add('MaxX :'+IntToStr(MaxX));
stats.Lines.Add('MaxID :'+IntToStr(MaxID));
stats.Lines.Add('MinX :'+IntToStr(MinX));
stats.Lines.Add('MinID :'+IntToStr(MinID));
stats.Lines.Add('povtor :'+VarToStr(povtor));
stats.Lines.Add('tame :'+VarToStr(tame)+' выч %хп');
stats.Lines.Add('gdo :'+VarToStr(gdo)+' центр окр');
stats.Lines.Add('Hpotion: '+inttostr(Hpotion));
stats.Lines.Add('Apotion: '+inttostr(Apotion));
// if (MaxHP<>0) then begin
info.Lines.Add('Ближайший МОБ: id='+IntToStr(MinID)+' дистанция='+IntToStr(MinX));
info.Lines.Add('HP:'+IntToStr(CurHP)+' из '+IntToStr(MaxHP)+' Цикл1='+IntToStr(attackk)+' Цикл2='+IntToStr(atck)+' Цикл бафа='+IntToStr(bfi));
if (Hpotion=0) then info.Lines.Add('Юзать HP бутылки?: НЕТ!');
if (Hpotion<>0) then info.Lines.Add('Юзать HP бутылки?: ДА!');
if (Apotion=0) then info.Lines.Add('Юзать AP бутылки?: НЕТ!');
if (Apotion<>0) then info.Lines.Add('Юзать AP бутылки?: ДА!');
if (sit=false) then info.Lines.Add('Бот стоит!');
if (sit=true) then info.Lines.Add('Бот сидит!');
for i:= 1 to last do begin
if (MobsID[i]<>0) then begin
if (attackIDMinID<>i) then info.Lines.Add('--'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
if (attackIDMinID=i) then info.Lines.Add('->'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
end;
end;
for i:= 1 to last do begin
if (MobsID[i]<>0) then begin
GameToMap(MobsX[i],MobsY[i]);
Shape[i].left:=xm; //координаты моба
Shape[i].top:=ym;
if Aggro[i]=true then Shape[i].Brush.Color:=clPurple;
end;
end;
// end;
if (MaxHP=0) then info.Lines.Add(' Для инициализации Бота используй аптечку!');
end;
//***************************************************************
procedure Free;
begin
DelALL;
end;
//***************************************************************
procedure StatsUpdate;
var
i: integer;
begin
for i:=0 to ReadD(6)-1 do begin
case pck[i*8+10] of
#$09: CurHP:=ReadD(i*8+14);
#$0A: MaxHP:=ReadD(i*8+14);
end;
end;
if (MaxHP<>0) then // вычисляем процентное соотношение хп
begin
but:=Round((MaxHP/100)*PercentHP); // при каком количестве хп юзать бутылку лечения
sud:=Round((MaxHP/100)*MEsit); // при каком количестве хп надо сесть и подкопить хп
bst:=Round((MaxHP/100)*MEup); // при каком количестве хп надо встать после отдыха
end;
end;
//***************************************************************
//ПЕРЕМЕЩЕНИЕ:
//Идти в точку с координатами x,y,z
//MOVETO(x,y,z)
procedure MoveTo(TargetX,TargetY,TargetZ:integer);
begin
//01=MoveBackwardToLocation:d(targetX)d(targetY)d(targetZ)d(originX)d(originY)d(originZ)d(moveByMouse)
buf:=#$01;
WriteD(targetx); //куда
WriteD(targety);
WriteD(targetz);
WriteD(MyXpos); //откуда
WriteD(MyYpos);
WriteD(MyZpos);
WriteD(1); //используем 1-мышь 0-клавиатура
SendToServerEx(Name);
msg.Lines.Add('MoveTo('+inttostr(targetx)+','+inttostr(targety)+','+inttostr(targetz)+')');
end;
//***************************************************************
//Ориентация на местности:
//Проверка находится ли заданная точка в пределах досягаемости. Если да, то выполняется кусок скрипта в фигурных скобках {}.
function PosInRange(targetx,targety,targetz,distanciya:extended):boolean;
begin
if delta(targetx, targety, MyXpos, MyYpos)<=distanciya
then result:=true else result:=false;
end;
//***************************************************************
function delta(xpos1, ypos1, xpos2, ypos2:extended):integer; //возвращает переменную rezu которая является растоянием между 2 точками
begin
result:= Round(Sqrt(((xpos1-xpos2)*(xpos1-xpos2))+((ypos1-ypos2)*(ypos1-ypos2))));
end;
//***************************************************************
procedure DelElArr(ele:integer); //удаляет моба!
begin
MobsID[ele]:=0;
MobsRAS[ele]:=0;
MobsX[ele]:=0;
MobsY[ele]:=0;
MobsZ[ele]:=0;
Aggro[ele]:=false;
Shape[ele].left:=-7; //координаты, чтобы небыло видно на карте
Shape[ele].top:=-7;
Shape[i].Brush.Color:=clGreen;
end;
//***************************************************************
procedure DelALL; //обнуляем всю базу!
var
i: integer;
begin
for i:= 1 to max do begin
NPCid[i]:=0;
MobsID[i]:=0;
MobsRAS[i]:=0;
MobsX[i]:=0;
MobsY[i]:=0;
MobsZ[i]:=0;
Aggro[i]:=false;
shape[i].free;
end;
shape[0].free;
timer1.Free;
timer2.Free;
timer3.Free;
info.Free;
msg.Free;
frm.Free;
map.Free;
end;
//***************************************************************
procedure GetMinMaxX(arra:array of integer);
//возвращает в переменную MinX - мин и MaxX - макс значение массива, а в MinID, MaxID номер этого элемента
var
i: integer;
begin
MinX:=5000;
MinID:=0;
MaxX:=0;
MaxID:=0;
for i:= 1 to last do begin
if (arra[i]<=MinX) and (arra[i]<>0) then begin
MinX:=arra[i];
MinID:=i;
end;
if (arra[i]>=MaxX) then begin
MaxX:=arra[i];
MaxID:=i;
end;
end;
end;
//***************************************************************
function ETOpovtor(chislo: integer; arra:array of integer):boolean;
//возвращает переменную povtor и если она равна 1 значит chislo уже есть в массиве!
var
i: integer;
begin
Result:=false;
for i:= 1 to last do begin
if (arra[i]=chislo) then Result:=true;
end;
end;
//***************************************************************
procedure attackt(mobus:integer);
begin
buf:=#$04; //action
WriteD(MobsID[mobus]);
WriteD(MyXpos);
WriteD(MyYpos);
WriteD(MyZpos);
WriteC(0);
SendToServerEx(Name);
end;
//***************************************************************
function Summ(sum:array of integer):integer;
//возвращает переменную SummaAR с количеством полных(не пустых) ячеек
var
Summa: integer;
i: integer;
begin
Result:=0;
for i:= 1 to max do begin
if (sum[i]<>0) then inc(Result);
end;
end;
//***************************************************************
procedure OnTimer1(Sender: TObject); //ВЫДЕЛЕНИЕ И АТАКА МОБА!!!!!!!!!!!!!
begin
//не всегда атакует по двойному клику, поэтому клики с задержкой в 1 сек.
//повторяем через 6 сек. двойной клик
if (MinID>0) then begin
if (sit=false) then begin
case attackk of
0: begin
msg.Lines.Add('Атакую! '+IntToStr(ID));
attackID:=MobsID[MinID];
attackIDMinID:=MinID;
attackt(attackIDMinID); //target
end;
//делаем паузу
1: begin
attackt(attackIDMinID); //attack
end;
6: begin
attackt(attackIDMinID); //target
end;
//делаем паузу
7: begin
attackt(attackIDMinID); //attack
attackk:=-1;
inc(atck);
end;
end;
//если стоим 35 сек ((attackk=7)*5), убираем текущий таргет и пробуем другой, вдруг поможет =)
case atck of
5: begin
MobsRAS[attackIDMinID]:=5000;
// GetMinMaxX(MobsRAS);
attackk:=-1;
atck:=0;
end;
end;
inc(attackk);
end;
end;
end;
//***************************************************************
procedure OnTimer2(Sender: TObject); //
begin
//контролируем бафы, если время бафов, то пытаемся бафаться каждую секунду
dec(bfi);
if bfi<0 then begin
timer3.interval:=1000; //каждые 1 сек
bfi:=1200; //20 мин
end;
//выводим в форму
ViewInfo;
GetMinMaxX(MobsRAS);
if (Summ(MobsRAS)>=round(max*0.9)) or (MaxX>5000) then begin
//если у нас занято более 90% ячеек с мобами надо удалить самых дальних от нас
msg.Lines.Add('мусор удалён:'+IntToStr(MaxID)+' :'+IntToStr(MaxX)+' сумма'+IntToStr(Summ(MobsRAS))+'-');
DelElArr(MaxID);
end;
//идем в центр если нет мобов. Это можно включить при желании,
//только будет мешать при управлении мобом
{
if (Summ(MobsRAS)=0) and (timer1.enabled=true) and (cvax<>0) then begin
if not PosInRange(cvaX,cvaY,cvaZ,50) then MoveTo(cvaX,cvaY,cvaZ);
end;
}
//лечимся в промежутках между битвами
if (CurHP<but) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add('Баффаюсь elemental heal!');
MagicSkillUse(elementalheal);
end;
//лечимся бутылками все время
if (CurHP<but) and (Hpotion<>0) then begin
if hpi=5 then begin
UseItem(Hpotion);
hpi:=0;
end else inc(hpi);
end;
//сидим если надо
if (CurHP<sud) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add(' все блин я отдыхаю!');
buf:=heal;
SendToServerEx(Name);
sit:=true;
end;
//встаем
if (CurHP>bst) and (sit=true) then begin
msg.Lines.Add(' пора за работу!');
buf:=heal;
SendToServerEx(Name);
attackk:=0;
atck:=0;
sit:=false;
end;
end;
//***************************************************************
procedure OnTimer3(Sender: TObject); //баффы
begin
//если никого не бъем, то надо бафаться
if (Summ(Aggro)=0) and (sit=false) then begin
case ii of
1: begin
timer1.enabled:=false; //откл. атаку
msg.Lines.Add('Баффаюсь Defense aura!');
//бафф
MagicSkillUse(buff1);
inc(ii);
timer3.interval:=6000; //каждые 6 сек
end;
2: begin
msg.Lines.Add('Баффаюсь Attack aura!');
MagicSkillUse(buff2);
inc(ii);
end;
3: begin
msg.Lines.Add('Баффаюсь Deflect arrow!');
MagicSkillUse(buff3);
inc(ii);
end;
4: begin
msg.Lines.Add('Баффаюсь Sprint!');
MagicSkillUse(buff4);
inc(ii);
end;
5: begin
msg.Lines.Add('Баффаюсь Spirit barrier!');
MagicSkillUse(buff5);
inc(ii);
timer3.interval:=10000; //каждые 10 сек
end;
6: begin
msg.Lines.Add('Баффаюсь Storm cubic!');
MagicSkillUse(cubicstorm);
inc(ii);
end;
7: begin
msg.Lines.Add('Баффаюсь Life cubic!');
MagicSkillUse(cubiclife);
inc(ii);
end;
8: begin
if Hpotion<>0 then begin
msg.Lines.Add('Potion of Alacrity!');
UseItem(Apotion);
end;
inc(ii);
end;
9: begin
ii:=1;
timer3.interval:=1150000; //каждые 20 мин
bfi:=1150;
timer1.enabled:=true; //вкл. атаку
end;
end;
end;
end;
//***************************************************************
procedure AddBD(id, posx, posy, posz:integer;); //добавляем моба в базу данных
var
i: integer;
begin
for i:=1 to last do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(id, MobsID)=false) then begin
MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsID[i])+'-ras-'+IntToStr(MobsRAS[i]));
GameToMap(posx,posy);
shape[i].left:=xm; //координаты моба
shape[i].top:=ym;
break;
end;
end;
end;
//если нет свободного места ищем дальше
for i:=last+1 to max do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(id, MobsID)=false) then begin
MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsID[i])+'-ras-'+IntToStr(MobsRAS[i]));
last:=i;
GameToMap(posx,posy);
shape[i].left:=xm; //координаты моба
shape[i].top:=ym;
break;
end;
end;
end;
end;
//***************************************************************
function ISnpc(id: integer;): boolean;
var
i: integer;
begin
result:=false;
for i:= 1 to max do if (NPCid[i]=id) then result:=true;
end;
//***************************************************************
procedure UseItem(ObjID:integer);
begin
buf:=#$14;
WriteD(ObjID);
WriteD(00);
SendToServerEx(Name);
end;
//***************************************************************
//2F=RequestMagicSkillUse:dMagicID)d(CtrlPressed)b(ShiftPressed)
procedure MagicSkillUse(MagicID:integer);
begin
buf:=#$2F;
WriteD(MagicID);
WriteD(00);
WriteC(00);
SendToServerEx(Name);
end;
//******************************************************************************
// вызывается при приходе каждого пакета, если скрипт включен
//******************************************************************************
begin
//****************************************************************************
//не обрабатываем пустые пакеты
if pck='' then exit;
//****************************************************************************
if (ConnectName=Name) and FromServer then begin
case pck[1] of
#$76: begin
msg.Lines.Add('S>C $76');
if (ReadD(2)=MyID) then begin //я юзнул какой то скилл
msg.Lines.Add(' юзнул скилл!');
skill:=1;
end;
end;
#$0E: begin
msg.Lines.Add('S>C $0E StatsUpdate');
if (MyID=ReadD(2)) then StatsUpdate; //обновление информации о хп
end;
//MagicSkillUse 48, Attack 05
#$05: begin
msg.Lines.Add('S>C $05 Attack');
if (ReadD(6)=MyID) then begin
//меня ударили
sit:=false;
if (ETOpovtor(ReadD(2),MobsID)=false) then AddBD(ReadD(2),ReadD(15),ReadD(19),ReadD(23));
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin //если моб записан в базе данных
msg.Lines.Add('На нас напали враги!!!'+IntToStr(i)+'-'+IntToStr(attackIDMinID));
MobsRAS[i]:=1;
Aggro[i]:=true; // стал агрессор
if (timer1.enabled=false) then begin //если я только зашел в игру и на меня напали
attackIDMinID:=i;
timer1.enabled:=true;
end;
if (attackIDMinID<>0) and (Aggro[attackIDMinID]=false) then attackIDMinID:=i;
break;
end;
end;
end;
end;
#$0C: begin
msg.Lines.Add('S>C $0C DropItem');
if (MyXpos<>0) then begin
if (delta(MyXpos, MyYpos, ReadD(14), ReadD(18))<=200) then begin
msg.Lines.Add('Выпала вещь!!!');
timer1.enabled:=false;
buf:=#$04;
WriteD(ReadD(6));
WriteD(ReadD(14));
WriteD(ReadD(18));
WriteD(ReadD(22));
WriteC(0);
SendToServerEx(Name);
msg.Lines.Add(' Пробую поднять!!!');
delay(1000);
timer1.enabled:=true;
end;
end;
end;
#$04: begin
msg.Lines.Add('S>C $04 CharInfo');
//пакет с инфой о моём чаре
i:=2;
MyXpos:=ReadD(i); //получаю координату х моего чара
MyYpos:=ReadD(i); //получаю координату у моего чара
MyZpos:=ReadD(i); //получаю координату z моего чара
GameToMap(MyXpos,MyYpos);
shape[0].left:=xm; //координаты моего чара
shape[0].top:=ym;
//Запоминаем ИД
i:=18;
MyID:=ReadD(i); //получаю ид моего чара
//смещение переменное, зависит от имени (LenName*2+2)
i:=i+(Length(Name)*2+2)+offs1; //44 для С4, 48 для IL
MaxHP:=ReadD(i);
CurHP:=ReadD(i);
if (gdo=false) then begin //задаем центр окружности кача
cvaX:=MyXpos;
cvaY:=MyYpos;
gdo:=true;
end;
end;
#$01: begin
msg.Lines.Add('S>C $01 Move');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если кто-то перемещается
i:=2;
ID:=ReadD(i); //кто-то рыпнулся с места надо это записать...
xpos:=ReadD(i);
ypos:=ReadD(i);
zpos:=ReadD(i);
if not ISnpc(ID) and (delta(cvaX,cvaY,xpos,ypos)<=Radius) then AddBD(ID,xpos,ypos,zpos);
end;
end;
//принят пакет Die
#$06: begin
msg.Lines.Add('S>C $06 Die');
//моб сдох! выкидываем его из базы and (attackID=ReadD(2))
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin
DelElArr(i);
attackk:=0;
atck:=0;
msg.Lines.Add('БОБИК СДОХ!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
//принят пакет DeleteObject
#$12: begin
msg.Lines.Add('S>C $12 DeleteObject');
//выкидываем из базы
for i:=1 to last do begin
if (MobsID[i]=ReadD(2)) then begin
DelElArr(i);
msg.Lines.Add('Удаляю из базы!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
#$03: begin
msg.Lines.Add('S>C $03 Char');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(18),NPCid)=false) then begin
NPCid[i]:=ReadD(18);
msg.Lines.Add('ИГРОК ДОБАВЛЕН!-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
#$16: begin
msg.Lines.Add('S>C $16 NPC');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
msg.Lines.Add('Вижу NPC!');
if (ReadD(10)=0) then begin //если нельзя атаковать
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(2), NPCid)=false) then begin
NPCid[i]:=ReadD(2);
msg.Lines.Add('Запомнили, NPCid='+IntToStr(ReadD(2))+' нельзя атаковать!');
break;
end;
end;
end;
end;
if (ReadD(10)=1) and (pck[120]=#$00) then begin //если можно атаковать
if (delta(cvaX, cvaY, ReadD(14), ReadD(18))<=RADIUS) then begin
AddBD(ReadD(2), ReadD(14), ReadD(18), ReadD(22));
msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' запомнили в базе!');
end
else msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' вне радиуса действия!');
end;
end;
end;
//InventoryUpdate
#$27: begin
msg.Lines.Add('S>C $27 InventoryUpdate');
if ((ReadD(12)=1060) or (ReadD(12)=1061)) then begin //Healing Potion, Lesser Healing Potion
Hpotion:=ReadD(8);
msg.Lines.Add('ID бутылок Hpotion:'+inttostr(Hpotion));
end;
if ReadD(12)=735 then begin //Potion of Alacrity
Apotion:=ReadD(8);
msg.Lines.Add('ID бутылок Apotion:'+inttostr(Apotion));
end;
end;
end;
end;
//****************************************************************************
if (ConnectName=Name) and FromClient then begin
case pck[1] of
#$1B: begin
msg.Lines.Add('C>S $1B ');
case ReadD(2) of
//социальное действие Yes для начала
$06: begin
cvaX:=MyXpos;
cvaY:=MyYpos;
cvaZ:=MyZpos;
attackk:=0;
atck:=0;
msg.Lines.Add('БОТ ВКЛЮЧЕН, координаты ОБНОВЛЕНЫ!!');
// GetMinMaxX(MobsRAS);
timer1.enabled:=true;
timer3.enabled:=true;
end;
//социальное действие No для окончания
$05: begin
timer1.enabled:=false;
timer3.enabled:=false;
msg.Lines.Add('БОТ ВЫКЛЮЧЕН!!!');
end;
{ //социальное действие Applaud
$0B: begin
if timer2.enabled=false
then timer2.enabled:=true
else timer2.enabled:=false;
attackk:=0;
atck:=0;
msg.Lines.Add('! ВКЛ/ВЫКЛ!!!');
end;
} //социальное действие Sorrow - удаляем текущую запись в базе
$0D: begin
ID:=MobsID[attackIDMinID];
DelElArr(attackIDMinID);
attackk:=0;
atck:=0;
msg.Lines.Add('Удаляем текущую запись в базе!!!');
for i:= last to max do begin
if (NPCid[i]=0) then begin
NPCid[i]:=ID;
msg.Lines.Add('ИГРОК ДОБАВЛЕН!-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
//ValidatePosition пакет от клиента с моими кординатами
#$48: begin
msg.Lines.Add('C>S $48 ValidatePosition');
//обновляем ВСЕ растояния в BD если мы сошли с места
MyXpos:=ReadD(2); //получаю координату х моего чара
MyYpos:=ReadD(6); //получаю координату у моего чара
MyZpos:=ReadD(10); //получаю координату z моего чара
GameToMap(MyXpos,MyYpos);
shape[0].left:=xm; //координаты моего чара
shape[0].top:=ym;
for i:=1 to last do begin
if (MobsID[i]<>0) then begin
if (true<>Aggro[i]) then begin
MobsRAS[i]:=delta(MyXpos,MyYpos,MobsX[i],MobsY[i]);
end;
end;
end;
end;
end;
end;
end.
Отличный скрипт, спасибо.
Но при каче в катах бот может взять в таргет цель, которая на поверхности. Можно ли сделать ограничение по Z в скрипте? Еще не понял вот этот момент: atck:=0; //кол-во неуспешных атак после которых пробуем сместиться. Какое значение лучше оставить и на что влияет? Бот возьмет другой таргет при неудачной атаке (если поставить значение "1") или вернется в центр зоны?
//Bot by Skymanrus
//modified by NLObP специально для Владера, моего сына!
{Бот для кача ТК 64+ лвл
Достоинства:
- миникарта;
- панель с инфой;
- бафает себя:
- юзает кубики;
- юзает пошин алакрити;
- лечит себя хил пошинами и элементал хилом;
- при желании можно отключить клиент
Скрипт распространяется как есть, и я не несу ответственности
за то, что ВЫ натворили у себя, его используя.}
//***************************************************************
const
name='NLObP'; //имя чара для которого включен скрипт
//установить константу в зависимости от типа игры (С4 или Интерлюд)
IL=false; //true - IL, false - C4
max=100; //максимальное значение массива
buff1=91; //бафф defense aura
buff2=77; //бафф attack aura
buff3=112; //бафф deflect arrow
buff4=230; //бафф sprint
buff5=123; //бафф spirit barrier
cubicstorm=10;
cubiclife=67;
elementalheal=58;
//***************************************************************
var
frm : TForm; //панель информации
info, msg, stats : TMemo;
splitter1, splitter2 : Tsplitter;
map : Tform; //виртуальная карта
xm, ym : integer; //координаты на карте
offs1 : integer; //смещение для типа игры Ил или С4
StartTime: TDateTime; //ведем подсчет времени
EndTime: TDateTime;
death1, mob1 : integer; //подсчитываем смерти
underAttack : boolean; //нас атакуют
heal, kill : string;
MaxHP, MyZpos, cvaZ, CurHP, ObjID, ID, xpos, ypos, skill, MyID, PercentHP, MEsit: integer;
MEup, but, sud, bst, Radius, cvaX, attackIDMinID, attackID, cvaY, zpos: integer;
Hpotion, Apotion, MyXpos, MyYpos, rezu, MaxX, MaxID, MinID, MinX: integer;
sit, povtor, tame, gdo, npc : Boolean;
attackk, bfi, atck, hpi, i, ii: integer; //индексы различных циклов
last : integer; //последняя запись в массиве, для ускорения скрипта
//массив мобов
MobsObjID: array[1..max] of integer;
MobsID: array[1..max] of integer;
MobsName: array[1..max] of string;
MobsRAS: array[1..max] of integer;
MobsX: array[1..max] of integer;
MobsY: array[1..max] of integer;
MobsZ: array[1..max] of integer;
NPCid: array[1..max] of integer;
Aggro: array[1..max] of Boolean;
TTShape: array [0..max] of Tshape; //объекты на карте
TTLabel: array [0..max] of Tlabel; //подписи к объектам
timer1: TTimer;
timer2: TTimer;
timer3: TTimer;
//***************************************************************
procedure Init; //УПРАВЛЯЮЩИЕ ПЕРЕМЕННЫЕ
var
i: integer;
begin
if il then begin
//CharInfo
offs1:=48; //44 для С4, 48 для IL
end else begin
offs1:=44;
end;
StartTime:=time;
underattack:=false; //атакован?
atck:=0; //кол-во неуспешных атак после которых пробуем сменить таргет, здесь инициализация =0
hpi:=0;
bfi:=60; //60 сек
ii:=1;
last:=1; //начальное значение
Radius:=1500; // радиус круга кача!
PercentHP:=70; // при каком количестве хп в % юзать бутылку лечения
MEsit:=55; // при каком количестве хп в % надо сесть и подкопить хп
MEup:=90; // при каком количестве хп в % надо встать после отдыха
frm := TForm.Create(nil);
frm.Caption := 'BOT '+name;
frm.BorderStyle := bsSizeable;
frm.Position := poScreenCenter;
frm.Width:=520;
frm.Height:=700;
info:=TMemo.Create(frm);
info.parent:=frm;
info.align:=alLeft;
info.ReadOnly:=true;
info.ScrollBars:=0;
info.Width:=370;
info.Height:=370;
// info.Lines.Add('БОТ НЕ ПОДКЛЮЧЁН К СЕРВЕРУ!');
stats:=TMemo.Create(frm);
stats.parent:=frm;
stats.align:=alClient;
stats.ReadOnly:=true;
stats.ScrollBars:=0;
stats.Width:=240;
stats.Height:=100;
msg:=TMemo.Create(frm);
msg.parent:=frm;
msg.align:=alBottom;
msg.ReadOnly:=true;
msg.ScrollBars:=2;
msg.Width:=520;
msg.Height:=100;
msg.Lines.Add('...');
splitter1:=Tsplitter.Create(frm);
splitter1.parent:=frm;
splitter1.Top:=0;
splitter1.Width:=3;
splitter1.Left:=470;
splitter1.align:=alLeft;
splitter2:=Tsplitter.Create(frm);
splitter2.parent:=frm;
splitter2.Left:=0;
splitter2.Height:=3;
splitter2.align:=alBottom;
frm.Show;
map := TForm.Create(nil);
map.Caption:='MiniMap: '+name;
map.BorderStyle:=bsDialog; //bsSizeable;
map.Position:=poScreencenter;
map.Width:=300;
map.Height:=300;
map.FormStyle:=FsStayOnTop;
map.Show;
heal:=HStr('45 00 00 00 00 00 00 00 00 00 '); // СИДЕТЬ!!!
//атака и прочее
timer1:=TTimer.Create(nil);
timer1.OnTimer:=@OnTimer1; //
timer1.enabled:=false; // таймер по умолчанию выключен
timer1.interval:=1000; // через каждые 1сек будем обновлять
//вывод в форму
timer2:=TTimer.Create(nil);
timer2.OnTimer:=@OnTimer2; //
timer2.enabled:=true; // таймер по умолчанию включен
timer2.interval:=1000; // через каждые 1сек будем обновлять
//баффы
timer3:=TTimer.Create(nil);
timer3.OnTimer:=@OnTimer3; //
timer3.enabled:=true; // таймер по умолчанию выключен
timer3.interval:=60000; // первый баф через 60 сек
for i:= 1 to max do begin
Aggro[i]:=false;
TTShape[i]:=Tshape.create(nil); //для мобов
TTShape[i].parent:=map;
TTShape[i].Brush.Color:=clBlue; //(clBlack, clRed, clGreen, clYellow, clBlue, clPurple)
TTShape[i].shape:=stCircle;
TTShape[i].left:=-70; //координаты
TTShape[i].top:=-70;
TTShape[i].width:=7; //размеры
TTShape[i].height:=7;
TTlabel[i]:=Tlabel.create(nil);
TTlabel[i].parent:=map;
TTlabel[i].left:=TTShape[i].left+4; //координаты
TTlabel[i].top:=TTShape[i].top+4;
TTlabel[i].caption:=inttostr(i);
TTlabel[i].font.size:=7;
TTlabel[i].font.color:=clBlue;
end;
TTshape[0]:=Tshape.create(nil); //для моего чара
TTshape[0].parent:=map;
TTshape[0].shape:=stCircle;
TTshape[0].Brush.Color:=clBlack;
TTshape[0].left:=-70; //координаты
TTshape[0].top:=-70;
TTshape[0].width:=5; //размеры
TTshape[0].height:=5;
TTlabel[0]:=Tlabel.create(nil); //для моего чара
TTlabel[0].parent:=map;
TTlabel[0].left:=TTShape[0].left+4; //координаты
TTlabel[0].top:=TTShape[0].top+4;
TTlabel[0].caption:=name;
TTlabel[0].font.size:=7;
TTlabel[0].font.color:=clBlack;
end;
//***************************************************************
procedure GameToMap(x, y : integer);
//преобразуем игровые координаты в координаты карты
var
masshtabx, masshtaby : extended;
begin
// masshtabx:=radius*2 div map.Width;
// masshtaby:=radius*2 div map.Height;
xm:=Round(((X-myXpos)*map.Width/6000)+(map.Width/2));
ym:=Round(((Y-myYpos)*map.Height/6000)+(map.Width/2)*0.9);
// xm:=Round(((X-cvaX)*map.Width/5000)+(map.Width/2));
// ym:=Round(((Y-cvaY)*map.Height/5000)+(map.Width/2));
end;
//***************************************************************
//RequestRestartPoint
//6D 00 00 00 00
procedure RequestRestartPoint;
begin
buf:=#$6D;
WriteD(00);
SendToServerEx(Name);
end;
//***************************************************************
procedure ViewInfo;
var
i: integer;
begin
info.Lines.Clear;
stats.Lines.Clear;
stats.Lines.Add('Имя чара :'+Name);
stats.Lines.Add('Время старта :'+TimeToStr(starttime));
stats.Lines.Add('Время работы :'+TimeToStr(time-starttime));
stats.Lines.Add('Убили МОБов: '+IntToStr(mob1)+' раз');
stats.Lines.Add('Погибли: '+IntToStr(death1)+' раз');
stats.Lines.Add('MaxHP :'+IntToStr(MaxHP));
stats.Lines.Add('CurHP :'+IntToStr(CurHP));
stats.Lines.Add('MyID :'+IntToStr(MyID));
stats.Lines.Add('MyXpos :'+IntToStr(MyXpos));
stats.Lines.Add('MyYpos :'+IntToStr(MyYpos));
stats.Lines.Add('MyZpos :'+IntToStr(MyZpos));
stats.Lines.Add('Radius :'+IntToStr(RADIUS));
stats.Lines.Add('cvaX :'+IntToStr(cvaX)+' центр к');
stats.Lines.Add('cvaY :'+IntToStr(cvaY)+' центр к');
stats.Lines.Add('cvaZ :'+IntToStr(cvaZ)+' центр к');
stats.Lines.Add('skill :'+IntToStr(skill)+' юзал скил');
stats.Lines.Add('but :'+IntToStr(but)+' бутылки');
stats.Lines.Add('sud :'+IntToStr(sud)+' сидеть');
stats.Lines.Add('bst :'+IntToStr(bst)+' встать');
stats.Lines.Add('ObjID :'+IntToStr(ObjID)+' кто ходит');
stats.Lines.Add('xpos :'+IntToStr(xpos)+' кто ходит');
stats.Lines.Add('ypos :'+IntToStr(ypos)+' кто ходит');
stats.Lines.Add('zpos :'+IntToStr(zpos)+' кто ходит');
stats.Lines.Add('sit :'+VarToStr(sit));
stats.Lines.Add('PercentHP :'+IntToStr(PercentHP)+' %хп');
stats.Lines.Add('MEsit :'+IntToStr(MEsit)+' %хп');
stats.Lines.Add('MEup :'+IntToStr(MEup)+' %хп');
stats.Lines.Add('attackIDMinID :'+IntToStr(attackIDMinID)+' ближний');
stats.Lines.Add('attackID :'+IntToStr(attackID)+' ближний');
stats.Lines.Add('attackk :'+IntToStr(attackk)+' цикл атак');
stats.Lines.Add('atck :'+IntToStr(atck)+' цикл неудачных атак');
stats.Lines.Add('Last :'+IntToStr(Last)+' последняя в бд');
stats.Lines.Add('SummaAR :'+IntToStr(Summ(MobsObjID))+' всего в бд');
stats.Lines.Add('rezu :'+IntToStr(delta(MyXpos, MyYpos, xpos, ypos))+' рез ближ');
stats.Lines.Add('MaxX :'+IntToStr(MaxX));
stats.Lines.Add('MaxID :'+IntToStr(MaxID));
stats.Lines.Add('MinX :'+IntToStr(MinX));
stats.Lines.Add('MinID :'+IntToStr(MinID));
stats.Lines.Add('povtor :'+VarToStr(povtor));
stats.Lines.Add('tame :'+VarToStr(tame)+' выч %хп');
stats.Lines.Add('gdo :'+VarToStr(gdo)+' центр окр');
stats.Lines.Add('Hpotion: '+inttostr(Hpotion));
stats.Lines.Add('Apotion: '+inttostr(Apotion));
stats.Lines.Add('xm :'+IntToStr(xm));
stats.Lines.Add('ym :'+IntToStr(ym));
// if (MaxHP<>0) then begin
info.Lines.Add('Ближайший МОБ: id='+IntToStr(MinID)+' дистанция='+IntToStr(MinX));
info.Lines.Add('HP:'+IntToStr(CurHP)+' из '+IntToStr(MaxHP)+' Цикл1='+IntToStr(attackk)+' Цикл2='+IntToStr(atck)+' Цикл бафа='+IntToStr(bfi));
if (Hpotion=0) then info.Lines.Add('Юзать HP бутылки?: НЕТ!');
if (Hpotion<>0) then info.Lines.Add('Юзать HP бутылки?: ДА!');
if (Apotion=0) then info.Lines.Add('Юзать AP бутылки?: НЕТ!');
if (Apotion<>0) then info.Lines.Add('Юзать AP бутылки?: ДА!');
if (sit=false) then info.Lines.Add('Бот стоит!');
if (sit=true) then info.Lines.Add('Бот сидит!');
for i:= 1 to last do begin
if (MobsObjID[i]<>0) then begin
if (attackIDMinID<>i) then info.Lines.Add('--'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsObjID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
if (attackIDMinID=i) then info.Lines.Add('->'+IntToStr(i)+' ID МОБа:'+IntToStr(MobsObjID[i])+' расстояние:'+IntToStr(MobsRAS[i])+' атакует:'+VarToStr(Aggro[i])+' x:'+IntToStr(MobsX[i])+' y:'+IntToStr(MobsY[i])+' z:'+IntToStr(MobsZ[i]));
end;
end;
for i:= 1 to last do begin
if (MobsObjID[i]<>0) then begin
GameToMap(MobsX[i],MobsY[i]);
TTShape[i].left:=xm; //координаты моба
TTShape[i].top:=ym;
TTlabel[i].left:=TTShape[i].left+4; //координаты
TTlabel[i].top:=TTShape[i].top+4;
TTlabel[i].caption:=inttostr(i);
if Aggro[i]=true then begin
TTShape[i].Brush.Color:=clPurple;
TTlabel[i].font.color:=clPurple;
end;
end;
end;
// end;
if (MaxHP=0) then info.Lines.Add('Для инициализации Бота используй аптечку!');
end;
//***************************************************************
procedure Free;
begin
DelALL;
end;
//***************************************************************
procedure StatsUpdate;
var
i: integer;
begin
for i:=0 to ReadD(6)-1 do begin
case pck[i*8+10] of
#$09: CurHP:=ReadD(i*8+14);
#$0A: MaxHP:=ReadD(i*8+14);
end;
end;
// if (MaxHP<>0) and (tame=false) then // вычисляем процентное соотношение хп
if (MaxHP<>0) then // вычисляем процентное соотношение хп
begin
but:=Round((MaxHP/100)*PercentHP); // при каком количестве хп юзать бутылку лечения
sud:=Round((MaxHP/100)*MEsit); // при каком количестве хп надо сесть и подкопить хп
bst:=Round((MaxHP/100)*MEup); // при каком количестве хп надо встать после отдыха
// tame:=true;
end;
end;
//***************************************************************
//ПЕРЕМЕЩЕНИЕ:
//Идти в точку с координатами x,y,z
//MOVETO(x,y,z)
procedure MoveTo(TargetX,TargetY,TargetZ:integer);
begin
//01=MoveBackwardToLocation:d(targetX)d(targetY)d(targetZ)d(originX)d(originY)d(originZ)d(moveByMouse)
buf:=#$01;
WriteD(targetx); //куда
WriteD(targety);
WriteD(targetz);
WriteD(MyXpos); //откуда
WriteD(MyYpos);
WriteD(MyZpos);
WriteD(1); //используем 1-мышь 0-клавиатура
SendToServerEx(Name);
msg.Lines.Add('MoveTo('+inttostr(targetx)+','+inttostr(targety)+','+inttostr(targetz)+')');
end;
//***************************************************************
//Ориентация на местности:
//Проверка находится ли заданная точка в пределах досягаемости. Если да, то выполняется кусок скрипта в фигурных скобках {}.
function PosInRange(targetx,targety,targetz,distanciya:extended):boolean;
begin
if delta(targetx, targety, MyXpos, MyYpos)<=distanciya
then result:=true else result:=false;
end;
//***************************************************************
function delta(xpos1, ypos1, xpos2, ypos2:extended):integer; //возвращает переменную rezu которая является растоянием между 2 точками
begin
result:= Round(Sqrt(((xpos1-xpos2)*(xpos1-xpos2))+((ypos1-ypos2)*(ypos1-ypos2))));
end;
//***************************************************************
procedure DelElArr(ele:integer); //удаляет моба!
begin
MobsObjID[ele]:=0;
MobsID[ele]:=0;
MobsName[ele]:='';
MobsRAS[ele]:=0;
MobsX[ele]:=0;
MobsY[ele]:=0;
MobsZ[ele]:=0;
Aggro[ele]:=false;
TTShape[ele].left:=-70; //координаты
TTShape[ele].top:=-70;
TTShape[ele].Brush.Color:=clBlue;
TTlabel[ele].left:=TTShape[ele].left+4; //координаты
TTlabel[ele].top:=TTShape[ele].top+4;
TTlabel[ele].caption:='';
TTlabel[ele].font.color:=clBlue;
end;
//***************************************************************
procedure DelALL; //обнуляем всю базу!
var
i: integer;
begin
for i:= 1 to max do begin
NPCid[i]:=0;
MobsObjID[i]:=0;
MobsID[i]:=0;
MobsName[i]:='';
MobsRAS[i]:=0;
MobsX[i]:=0;
MobsY[i]:=0;
MobsZ[i]:=0;
Aggro[i]:=false;
TTshape[i].free;
TTlabel[i].free;
end;
TTshape[0].free;
TTlabel[0].free;
timer1.Free;
timer2.Free;
timer3.Free;
info.Free;
msg.Free;
frm.Free;
map.Free;
end;
//***************************************************************
procedure GetMinMaxX(arra:array of integer);
//возвращает в переменную MinX - мин и MaxX - макс значение массива, а в MinID, MaxID номер этого элемента
var
minras, i: integer;
begin
MinX:=5000;
MinID:=0;
MaxX:=0;
MaxID:=0;
for i:= 1 to last do begin
if (delta(Mobsx[i],Mobsy[i],cvaX,cvaY)<=Radius) then begin
if (arra[i]<=MinX) and (arra[i]<>0) then begin
MinX:=arra[i];
MinID:=i;
end;
if (arra[i]>=MaxX) then begin
MaxX:=arra[i];
MaxID:=i;
end;
end;
end;
end;
//***************************************************************
function ETOpovtor(chislo: integer; arra:array of integer):boolean;
//возвращает переменную povtor и если она равна 1 значит chislo уже есть в массиве!
var
i: integer;
begin
Result:=false;
for i:= 1 to last do begin
if (arra[i]=chislo) then Result:=true;
end;
end;
//***************************************************************
procedure attackt(mobus:integer);
begin
buf:=#$04; //action
WriteD(MobsObjID[mobus]);
WriteD(MyXpos);
WriteD(MyYpos);
WriteD(MyZpos);
WriteC(0);
SendToServerEx(Name);
end;
//***************************************************************
function Summ(sum:array of integer):integer;
//возвращает переменную SummaAR с количеством полных(не пустых) ячеек
var
Summa: integer;
i: integer;
begin
Result:=0;
for i:= 1 to max do begin
if (sum[i]<>0) then inc(Result);
end;
end;
//***************************************************************
procedure OnTimer1(Sender: TObject); //ВЫДЕЛЕНИЕ И АТАКА МОБА!!!!!!!!!!!!!
begin
if (MinID>0) then begin
if (sit=false) then begin
case attackk of
0: begin
attackID:=MobsObjID[MinID];
msg.Lines.Add('Атакую! '+IntToStr(attackID));
attackIDMinID:=MinID;
attackt(attackIDMinID); //target
end;
//делаем паузу
1: begin
attackt(attackIDMinID); //attack
end;
6: begin
attackt(attackIDMinID); //target
end;
//делаем паузу
7: begin
attackt(attackIDMinID); //attack
attackk:=1;
inc(atck);
end;
end;
//пробуем сместиться
case atck of
9: begin
MobsRAS[attackIDMinID]:=5000;
// GetMinMaxX(MobsRAS);
attackk:=-1;
atck:=0;
end;
end;
inc(attackk);
end;
end;
end;
//***************************************************************
procedure OnTimer2(Sender: TObject); //
begin
//контролируем бафы
dec(bfi);
if bfi<0 then begin
timer3.interval:=1000; //каждые 1 сек
bfi:=1200; //20 мин
end;
//выводим в форму
ViewInfo;
GetMinMaxX(MobsRAS);
if (Summ(MobsRAS)>=round(max*0.9)) or (MaxX>5000) then begin
//если у нас занято более 90% ячеек с мобами надо удалить самых дальних от нас
msg.Lines.Add('мусор удалён:'+IntToStr(MaxID)+' :'+IntToStr(MaxX)+' сумма'+IntToStr(Summ(MobsRAS))+'-');
DelElArr(MaxID);
end;
//идем в центр если нет мобов
// if (Summ(MobsRAS)=0) and (timer1.enabled=true) and (cvax<>0) then begin
//if not PosInRange(cvaX,cvaY,cvaZ,50) then MoveTo(cvaX,cvaY,cvaZ);
// end;
if (CurHP<but) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add('Баффаюсь elemental heal!');
MagicSkillUse(elementalheal);
end;
if (CurHP<but) and (Hpotion<>0) then begin
if hpi=5 then begin
UseItem(Hpotion);
hpi:=0;
end else inc(hpi);
end;
if (CurHP<sud) and (Summ(Aggro)=0) and (sit=false) then begin
msg.Lines.Add('все блин я отдыхаю!');
buf:=heal;
SendToServerEx(Name);
sit:=true;
end;
if (CurHP>bst) and (sit=true) then begin
msg.Lines.Add('пора за работу!');
buf:=heal;
SendToServerEx(Name);
attackk:=0;
atck:=0;
sit:=false;
end;
end;
//***************************************************************
procedure OnTimer3(Sender: TObject); //баффы
begin
if (Summ(Aggro)=0) and (sit=false) then begin
case ii of
1: begin
timer1.enabled:=false; //откл. атаку
msg.Lines.Add('Баффаюсь Defense aura!');
//бафф
MagicSkillUse(buff1);
inc(ii);
timer3.interval:=6000; //каждые 6 сек
end;
2: begin
msg.Lines.Add('Баффаюсь Attack aura!');
MagicSkillUse(buff2);
inc(ii);
end;
3: begin
msg.Lines.Add('Баффаюсь Deflect arrow!');
MagicSkillUse(buff3);
inc(ii);
end;
4: begin
msg.Lines.Add('Баффаюсь Sprint!');
MagicSkillUse(buff4);
inc(ii);
end;
5: begin
msg.Lines.Add('Баффаюсь Spirit barrier!');
MagicSkillUse(buff5);
inc(ii);
timer3.interval:=10000; //каждые 10 сек
end;
6: begin
msg.Lines.Add('Баффаюсь Storm cubic!');
MagicSkillUse(cubicstorm);
inc(ii);
end;
7: begin
msg.Lines.Add('Баффаюсь Life cubic!');
MagicSkillUse(cubiclife);
inc(ii);
end;
8: begin
if Hpotion<>0 then begin
msg.Lines.Add('Potion of Alacrite!');
UseItem(Apotion);
end;
inc(ii);
end;
9: begin
ii:=1;
timer3.interval:=1150000; //каждые 20 мин
bfi:=1150;
timer1.enabled:=true; //вкл. атаку
end;
end;
end;
end;
//***************************************************************
procedure AddBD(objid, posx, posy, posz:integer;); //добавляем моба в базу данных
var
i: integer;
begin
for i:=1 to last do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsObjID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(objid, MobsObjID)=false) then begin
MobsObjID[i]:=objid; //ид моба
// if id<>0 then MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsObjID[i])+'-ras-'+IntToStr(MobsRAS[i]));
GameToMap(posx,posy);
TTshape[i].left:=xm; //координаты моего чара
TTshape[i].top:=ym;
TTlabel[i].left:=TTShape[i].left+4; //координаты
TTlabel[i].top:=TTShape[i].top+4;
TTlabel[i].caption:=inttostr(i);
break;
end;
end;
end;
//если нет свободного места ищем дальше
for i:=last+1 to max do begin //перебираем базу и ищем свободную ячейку в ней
if (MobsObjID[i]=0) then begin //запоминаем моба в свободную ячейку
if (ETOpovtor(objid, MobsObjID)=false) then begin
MobsObjID[i]:=objid; //ид моба
if id<>0 then MobsID[i]:=id; //ид моба
MobsRAS[i]:=delta(MyXpos, MyYpos, posx, posy); //растояние до этого моба
MobsX[i]:=posx;
MobsY[i]:=posy;
MobsZ[i]:=posz;
msg.Lines.Add('!-'+IntToStr(i)+'-id-'+IntToStr(MobsObjID[i])+'-ras-'+IntToStr(MobsRAS[i]));
last:=i;
GameToMap(posx,posy);
TTshape[i].left:=xm; //координаты моего чара
TTshape[i].top:=ym;
TTlabel[i].left:=TTShape[i].left+4; //координаты
TTlabel[i].top:=TTShape[i].top+4;
TTlabel[i].caption:=inttostr(i);
break;
end;
end;
end;
end;
//***************************************************************
function ISnpc(id: integer;): boolean;
var
i: integer;
begin
result:=false;
for i:= 1 to max do if (NPCid[i]=id) then result:=true;
end;
//***************************************************************
procedure UseItem(ItemObjID:integer);
begin
buf:=#$14;
WriteD(ItemObjID);
WriteD(00);
SendToServerEx(Name);
end;
//***************************************************************
//2F=RequestMagicSkillUse:dMagicID)d(CtrlPressed)b(ShiftPressed)
procedure MagicSkillUse(MagicID:integer);
begin
buf:=#$2F;
WriteD(MagicID);
WriteD(00);
WriteC(00);
SendToServerEx(Name);
end;
//******************************************************************************
// вызывается при приходе каждого пакета, если скрипт включен
//******************************************************************************
begin
//****************************************************************************
//не обрабатываем пустые пакеты
if pck='' then exit;
//****************************************************************************
if (ConnectName=Name) and FromServer then begin
case pck[1] of
{ #$76: begin
msg.Lines.Add('S>C $76');
if (ReadD(2)=MyID) then begin //я юзнул какой то скилл
msg.Lines.Add(' юзнул скилл!');
skill:=1;
end;
end;
} #$0E: begin
msg.Lines.Add('S>C $0E StatsUpdate');
if (MyID=ReadD(2)) then StatsUpdate; //обновление информации о хп
end;
//MagicSkillUse 48, Attack 05
#$05: begin
msg.Lines.Add('S>C $05 Attack');
if (ReadD(6)=MyID) then begin
//меня ударили
sit:=false;
if (ETOpovtor(ReadD(2),MobsObjID)=false) then AddBD(ReadD(2),ReadD(15),ReadD(19),ReadD(23));
for i:=1 to last do begin
if (MobsObjID[i]=ReadD(2)) then begin //если моб записан в базе данных
msg.Lines.Add('На нас напали враги!!!'+IntToStr(i)+'-'+IntToStr(MobsObjID[i]));
MobsRAS[i]:=1;
Aggro[i]:=true; // стал агрессор
if (timer1.enabled=false) then begin //если я только зашел в игру и на меня напали
attackIDMinID:=i;
timer1.enabled:=true;
end;
if (attackIDMinID<>0) and (Aggro[attackIDMinID]=false) then attackIDMinID:=i;
break;
end;
end;
end;
end;
#$0C: begin
msg.Lines.Add('S>C $0C DropItem');
if (MyXpos<>0) then begin
if (delta(MyXpos, MyYpos, ReadD(14), ReadD(18))<=200) then begin
msg.Lines.Add('Выпала вещь!!!');
timer1.enabled:=false;
buf:=#$04;
WriteD(ReadD(6));
WriteD(ReadD(14));
WriteD(ReadD(18));
WriteD(ReadD(22));
WriteC(0);
SendToServerEx(Name);
msg.Lines.Add(' Пробую поднять!!!');
delay(1000);
timer1.enabled:=true;
end;
end;
end;
#$04: begin
msg.Lines.Add('S>C $04 CharInfo');
//пакет с инфой о моём чаре
i:=2;
MyXpos:=ReadD(i); //получаю координату х моего чара
MyYpos:=ReadD(i); //получаю координату у моего чара
MyZpos:=ReadD(i); //получаю координату z моего чара
//Запоминаем ИД
i:=18;
MyID:=ReadD(i); //получаю ид моего чара
//смещение переменное, зависит от имени (LenName*2+2)
i:=i+(Length(Name)*2+2)+offs1; //44 для С4, 48 для IL
MaxHP:=ReadD(i);
CurHP:=ReadD(i);
if (gdo=false) then begin //задаем центр окружности кача
cvaX:=MyXpos;
cvaY:=MyYpos;
gdo:=true;
end;
GameToMap(MyXpos,MyYpos);
TTshape[0].left:=xm; //координаты моего чара
TTshape[0].top:=ym;
TTlabel[0].left:=TTShape[0].left+4; //координаты
TTlabel[0].top:=TTShape[0].top+4;
end;
#$01: begin
msg.Lines.Add('S>C $01 Move');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если кто-то перемещается
i:=2;
ObjID:=ReadD(i); //кто-то рыпнулся с места надо это записать...
ID:=0; //кто-то рыпнулся с места надо это записать...
xpos:=ReadD(i);
ypos:=ReadD(i);
zpos:=ReadD(i);
if not ISnpc(ObjID) {and (delta(cvaX,cvaY,xpos,ypos)<=Radius)} then AddBD(ObjID,xpos,ypos,zpos);
end;
end;
//принят пакет Die
#$06: begin
msg.Lines.Add('S>C $06 Die');
//нас убили
if (myID=ReadD(2)) then begin
info.Lines.Add('Нас убили в '+TimeToStr(time));
inc(death1);
RequestRestartPoint; //оживаем после смерти
// mov:=1;
//TODO сделать проверки на место появления
// moveto1.enabled:=true;
info.Lines.Add('Бежим после смерти на берег...');
underattack:=false;
for i:= 1 to max do begin
Aggro[i]:=false;
TTShape[i].Brush.Color:=clBlue;
TTlabel[i].font.color:=clBlue;
end;
end;
//моб сдох! выкидываем его из базы and (attackID=ReadD(2))
for i:=1 to last do begin
if (MobsObjID[i]=ReadD(2)) then begin
inc(mob1);
DelElArr(i);
attackk:=0;
atck:=0;
msg.Lines.Add('БОБИК СДОХ!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
//принят пакет DeleteObject
#$12: begin
msg.Lines.Add('S>C $12 DeleteObject');
//выкидываем из базы
for i:=1 to last do begin
if (MobsObjID[i]=ReadD(2)) then begin
DelElArr(i);
msg.Lines.Add('Удаляю из базы!! :'+IntToStr(i));
if (i=last) and (last<>1) then dec(last);
break;
end;
end;
end;
#$03: begin
msg.Lines.Add('S>C $03 Char');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(18),NPCid)=false) then begin
NPCid[i]:=ReadD(18);
msg.Lines.Add('ДОБАВЛЕН ИГРОК:'+ReadS(22)+'-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
#$16: begin
msg.Lines.Add('S>C $16 NPC');
if (MyID<>0) and (ReadD(2)<>MyID) then begin //если это не я
msg.Lines.Add('Вижу NPC!');
if (ReadD(10)=0) then begin //если нельзя атаковать
for i:=last to max do begin
if (NPCid[i]=0) then begin
if (ETOpovtor(ReadD(2), NPCid)=false) then begin
NPCid[i]:=ReadD(2);
msg.Lines.Add('Запомнили, NPCid='+IntToStr(ReadD(2))+' нельзя атаковать!');
break;
end;
end;
end;
end;
if (ReadD(10)=1) and (pck[120]=#$00) then begin //если можно атаковать
// if (delta(cvaX, cvaY, ReadD(14), ReadD(18))<=Radius) then begin
id:=ReadD(6);
AddBD(ReadD(2), ReadD(14), ReadD(18), ReadD(22));
msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' запомнили в базе!');
// end
// else msg.Lines.Add('NPCid='+IntToStr(ReadD(2))+' вне радиуса действия!');
end;
end;
end;
//InventoryUpdate
#$27: begin
msg.Lines.Add('S>C $27 InventoryUpdate');
if ((ReadD(12)=1060) or (ReadD(12)=1061)) then begin //Healing Potion, Lesser Healing Potion
Hpotion:=ReadD(8);
msg.Lines.Add('ID бутылок Hpotion:'+inttostr(Hpotion));
end;
if ReadD(12)=735 then begin //Potion of Alacrity
Apotion:=ReadD(8);
msg.Lines.Add('ID бутылок Apotion:'+inttostr(Apotion));
end;
end;
end;
end;
//****************************************************************************
if (ConnectName=Name) and FromClient then begin
case pck[1] of
#$1B: begin
msg.Lines.Add('C>S $1B ');
case ReadD(2) of
//социальное действие Yes для начала
$06: begin
cvaX:=MyXpos;
cvaY:=MyYpos;
cvaZ:=MyZpos;
GameToMap(MyXpos,MyYpos);
TTshape[0].left:=xm; //координаты моего чара
TTshape[0].top:=ym;
TTlabel[0].left:=TTShape[0].left+4; //координаты
TTlabel[0].top:=TTShape[0].top+4;
attackk:=0;
atck:=0;
msg.Lines.Add('БОТ ВКЛЮЧЕН, координаты ОБНОВЛЕНЫ!!');
// GetMinMaxX(MobsRAS);
timer1.enabled:=true;
timer3.enabled:=true;
end;
//социальное действие No для окончания
$05: begin
timer1.enabled:=false;
timer3.enabled:=false;
msg.Lines.Add('БОТ ВЫКЛЮЧЕН!!!');
end;
{ //социальное действие Applaud
$0B: begin
if timer2.enabled=false
then timer2.enabled:=true
else timer2.enabled:=false;
attackk:=0;
atck:=0;
msg.Lines.Add('! ВКЛ/ВЫКЛ!!!');
end;
} //социальное действие Sorrow - удаляем текущую запись в базе
$0D: begin
ObjID:=MobsObjID[attackIDMinID];
DelElArr(attackIDMinID);
attackk:=0;
atck:=0;
msg.Lines.Add('Удаляем текущую запись в базе!!!');
for i:= last to max do begin
if (NPCid[i]=0) then begin
NPCid[i]:=ObjID;
msg.Lines.Add('ИГРОК ДОБАВЛЕН!-'+IntToStr(i)+'--'+IntToStr(NPCid[i]));
break;
end;
end;
end;
end;
end;
//ValidatePosition пакет от клиента с моими кординатами
#$48: begin
msg.Lines.Add('C>S $48 ValidatePosition');
//обновляем ВСЕ растояния в BD если мы сошли с места
MyXpos:=ReadD(2); //получаю координату х моего чара
MyYpos:=ReadD(6); //получаю координату у моего чара
MyZpos:=ReadD(10); //получаю координату z моего чара
GameToMap(MyXpos,MyYpos);
TTshape[0].left:=xm; //координаты моего чара
TTshape[0].top:=ym;
TTlabel[0].left:=TTShape[0].left+4; //координаты
TTlabel[0].top:=TTShape[0].top+4;
for i:=1 to last do begin
if (MobsObjID[i]<>0) then begin
if (true<>Aggro[i]) then begin
MobsRAS[i]:=delta(MyXpos,MyYpos,MobsX[i],MobsY[i]);
end;
end;
end;
end;
end;
end;
end.
Добавлено спустя 21 минуту 31 секунду:
Цитата:
Сообщение от Юзер
Отличный скрипт, спасибо.
Но при каче в катах бот может взять в таргет цель, которая на поверхности. Можно ли сделать ограничение по Z в скрипте? Еще не понял вот этот момент: atck:=0; //кол-во неуспешных атак после которых пробуем сместиться. Какое значение лучше оставить и на что влияет? Бот возьмет другой таргет при неудачной атаке (если поставить значение "1") или вернется в центр зоны?
Спасибо.
В катах можно попробовать сильно уменьшить RADIUS - радиус кача.
Ограничение по Z можно сделать, например типа такого
Код:
const DeltaZ=200;
...
//NPCInfo, запоминаем мобов
if FromServer and (ConnectName=Name) and (pck[1]=#$16) then begin
...
//проверям, не под землей ли моб(в катакомбах)
tempZ:=BotCoordZ-ReadD(22);
if abs(tempZ)<=DeltaZ then begin
for i:=1 to max do begin
...
Переменная atck и attackk используются в процедуре OnTimer1.
attackk - нужна для контроля атаки
atck - если вдруг застряли - пытаемся изменить цель (через время atck(5) * attackk(7) = 35 сек)
цель меняется даже если не застряли но вреемя вышло, можно подкорректировать время в нужную сторону