Рыцарь
Регистрация: 25.02.2008
Адрес: г.Волгоград
Сообщений: 2,009
Сказал Спасибо: 1,285
Имеет 1,458 спасибок в 793 сообщенях
|
Re: ДА БУДЕТ БОТ!
В дополнение к скрипту "кач дракона" выкладываю "ботика".
Возможности скрипта: Сам атакует, сам подбирает дроп относительно выбранного нами центра.
Внесены изменения для отличия игроков от мобов, работает в случае если игрок прибежал из-за границы видимости. Если он рядом то бот принимает его за цель. Атаковать не будет, так как не зажат контрол.
Все сообщения по SAY можно закомментить, они только для отладки скрипта. Скрипт в процессе разработки.
Изменяем константы: Name, Pet, Radius, DeltaZ, по желанию max. Для инициализации скрипта надо получить пакет UserInfo(04). Как пример: открыть инвентарь, напасть на моба. Включить работу скрипта соц.действие Yes. Остановить No.
Спасибо Ворону за его "Локомотив"!
Код:
//БОТ with 'Hachling of Star' by NLObP
//******************************************************************************
Const
Name='NLObP'; //имя чара
Pet=''; //имя Пета
max=50; //max количество контролируемых мобов
Radius=1500; //радиус участка для поиска мобов
DeltaZ=250; //глубина/высота до мобов
//******************************************************************************
VAR
NameChar: string;
CentrKachX,CentrKachY,RadiusKachX,RadiusKachY, CharID, PetID, Attacker, ObjectID: integer;
CentrKachXex,CentrKachYex,RadiusKachXex,RadiusKachYex: extended;
tempX,tempY, tempLenght: extended;
tempZ: integer;
ColvoMobs, ColvoMobs2: integer;
CurHP, MaxHP, CurMP, MaxMP, time1 :integer;
BotCoordX,BotCoordY,BotCoordZ: integer; //координаты бота
BotCoordXext,BotCoordYext,BotCoordZext:extended;
MinPutID: integer; //указывает индекс моба в базе путь до которого самый короткий
MinPutLenght: extended; //квадрат расстояния до ближайшего моба
timer1: TTimer; //основной таймер
timer2: TTimer; //вспомогательный
i, itm, SocialID:integer; // вспомогательная
AddMob, UnderAttack, scrready: boolean;
NeedBackup:boolean;
ItemBase: array[1..4,1..max] of integer; // описатель предметов
CharBase: array[1..4,1..max] of integer; // описатель игроков (которых не атакуем)
MobBase: array[1..4,1..max] of integer; // описатель мобов вокруг
MobBaseExt: array[1..4,1..max] of extended; // описатель мобов вокруг вспомогательная
{
1 - ID
2 - X
3 - Y
4 - Z
5 - Attakable //агрессивные?
}
//******************************************************************************
procedure Init; //Вызывается при включении скрипта
begin
UnderAttack:=false;
itm:=0;
NeedBackup:=false;
scrready:=false;
colvomobs:=0;
colvomobs2:=0;
timer1:=TTimer.Create(nil);
timer1.OnTimer:=@OnTimer1; //
timer1.enabled:=False; //
timer1.interval:=2000;
timer2:=TTimer.Create(nil);
timer2.OnTimer:=@OnTimer2;
timer2.enabled:=false; //
timer2.interval:=15000;
end;
//******************************************************************************
procedure Free; //Вызывается при выключении скрипта
begin
timer1.Free;
timer2.Free;
end;
//******************************************************************************
//для отладки скрипта
procedure Say(msg:string);
begin
buf:=hstr('4A 00 00 00 00');
WriteD(2);
WriteS(Name);
WriteS(msg);
SendToClientEx(Name);
end;
//*******************************************************************
function Wait(var tick:integer; Timewait: Integer): Boolean;
// сквозная проверка без остановки скрипта (c)dmitry501
// modifed by Sh00rGo
var
t: integer;
begin
result:=false;
t:=Round(Time*86400);
if t>(tick+Timewait/1000) then begin
if tick>0 then result:=true;
tick:=t;
end;
end;
//******************************************************************************
procedure OnTimer2(Sender: TObject);
begin
//say('Вышло время');
UnderAttack:=false; //отцепимся от атакуемого
if itm>0 then needbackup:=true;
end;
//******************************************************************************
procedure ReqGetItem;
begin
if itm=0 then begin
timer1.enabled:=true; //включаем отсчет времени
needbackup:=false;
exit;
end;
timer1.enabled:=false; //выключаем отсчет времени
//перебираем базу
for i:=1 to max do begin
//если нашли, то обнуляем
if (ItemBase[1,i]<>0) then begin //ObjectID
say('ReqGetItem');
//даем команду подобрать вещь
buf:=#$04;
WriteD(ItemBase[1,i]);
WriteD(ItemBase[2,i]);
WriteD(ItemBase[3,i]);
WriteD(ItemBase[4,i]);
WriteH(00);
SendToServerEx(Name);
end;
end;
end;
//******************************************************************************
procedure OnTimer1(Sender: TObject);
begin
if UnderAttack then begin
TargetAttacker(Attacker);
exit;
end;
//say('Вычисляем ближайшего');
MinPutID:=0;
MinPutLenght:=99999999;
///ищем самого близково к нам моба
for i:=1 to max do begin
if (MobBaseExt[1,i]<>0) then begin
tempX:=MobBaseExt[2,i];
tempY:=MobBaseExt[3,i];
//теорема Пифагора c^2=a^2+b^2
tempLenght:=int(sqrt((BotCoordXext-tempx)*(BotCoordXext-tempx)+(BotCoordYext-tempy)*(BotCoordYext-tempy)));
if (tempLenght<MinPutLenght) and (PetID<>MobBase[1,i]) and (CharID<>MobBase[1,i]) then begin
MinPutLenght:=tempLenght;
MinPutID:=i;
//say('MinPutID='+inttostr(MinPutID)+' MinPutLenght='+Floattostr(MinPutLenght));
end;
end;
end;
say('MinPutID='+inttostr(MinPutID)+' MinPutLenght='+Floattostr(MinPutLenght));
if (minputid<>0) then begin
Attacker:=MobBase[1,MinPutID];
TargetAttacker(Attacker);
say('Attack!');
UnderAttack:=true; //зацепимся за атакуемого
end;
end;
//******************************************************************************
procedure TargetAtt;
begin
buf:=#$04;
WriteD(Attacker);
WriteD(BotCoordX);
WriteD(BotCoordY);
WriteD(BotCoordZ);
WriteC(00);
SendToServerEx(Name);
end;
//******************************************************************************
procedure TargetAttacker(Attacker: Integer);
begin
TargetAtt;
TargetAtt;
end;
//******************************************************************************
// вызывается при приходе каждого пакета если скрипт включен
//******************************************************************************
begin
//****************************************************************************
if pck='' then exit;
//****************************************************************************
//NPCInfo, запоминаем мобов
if FromServer and (ConnectName=Name) and (pck[1]=#$16) then begin
AddMob:=true;
//проверка, входит моб в радиус действия?
tempX:=ReadD(14); //x
tempY:=ReadD(18); //y
tempLenght:=sqrt((CentrKachXex-tempX)*(CentrKachXex-tempX)+(CentrKachYex-tempY)*(CentrKachYex-tempY));
//say('tempX='+Floattostr(tempX)+' tempY='+Floattostr(int(tempY)));
//say('Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
tempZ:=BotCoordZ-ReadD(22);
if tempz<0 then tempZ:=tempz*(-1);
//say('TempZ='+inttostr(tempz));
//say('BotCoordZ='+inttostr(BotCoordZ));
//say('MobCoordZ='+inttostr(readd(22)));
if tempZ<=DeltaZ then begin
if (tempLenght<Radius) then begin
for i:=1 to max do begin
//если нашли Моба в базе, то коректируем его координаты на новые
if (MobBase[1,i]=ReadD(2)) and (CharID<>ReadD(2)) and (PetID<>ReadD(2)) then begin
MobBase[2,i]:=ReadD(14); //x
MobBase[3,i]:=ReadD(18); //y
MobBase[4,i]:=ReadD(22); //z
//Ext массив
MobBaseExt[2,i]:=ReadD(14); //x
MobBaseExt[3,i]:=ReadD(18); //y
MobBaseExt[4,i]:=ReadD(22); //z
AddMob:=false;
//say('Корректируем координаты Моба'+' ColvoMobs='+inttostr(colvomobs));
//say('Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
end;
end;
//иначе, перебираем базу, ищем свободную ячейку в ней и добавляем нового моба
for i:=1 to max do begin
if (MobBase[1,i]=0) and AddMob and (CharID<>ReadD(2)) and (PetID<>ReadD(2)) then begin
//запоминаем моба в свободную ячейку
MobBase[1,i]:=ReadD(2); //ObjectID
MobBase[2,i]:=ReadD(14); //x
MobBase[3,i]:=ReadD(18); //y
MobBase[4,i]:=ReadD(22); //z
//Ext массив
MobBaseExt[1,i]:=ReadD(2); //ObjectID
MobBaseExt[2,i]:=ReadD(14); //x
MobBaseExt[3,i]:=ReadD(18); //y
MobBaseExt[4,i]:=ReadD(22); //z
inc(colvomobs);
say('Запоминаем координаты Моба'+' ColvoMobs='+inttostr(colvomobs));
//say('Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
break;
end;
end;
end;
end;
end;
//****************************************************************************
//CharInfo, запоминаем мобов
if FromServer and (ConnectName=Name) and (pck[1]=#$03) then begin
AddMob:=true;
for i:=1 to max do begin
//если нашли Моба в базе, то коректируем его координаты на новые
if (CharBase[1,i]=ReadD(18)) then begin
CharBase[2,i]:=ReadD(2); //x
CharBase[3,i]:=ReadD(6); //y
CharBase[4,i]:=ReadD(10); //z
AddMob:=false;
//say('Корректируем координаты Игрока');
end;
end;
//иначе, перебираем базу, ищем свободную ячейку в ней и добавляем нового моба
for i:=1 to max do begin
if (CharBase[1,i]=0) and AddMob then begin
//запоминаем моба в свободную ячейку
CharBase[1,i]:=ReadD(18); //ObjectID
CharBase[2,i]:=ReadD(2); //x
CharBase[3,i]:=ReadD(6); //y
CharBase[4,i]:=ReadD(10); //z
NameChar:=ReadS(22);
say('Приближается Игрок '+NameChar+'!!!');
break;
end;
end;
end;
//****************************************************************************
//MoveToLocation, коректируем координаты мобов в базе
if FromServer and (ConnectName=Name) and (pck[1]=#$01) then begin
//say('MoveToLocation');
AddMob:=true;
//проверка, входит моб в радиус действия?
tempX:=ReadD(6); //x
tempY:=ReadD(10); //y
tempLenght:=sqrt((CentrKachXex-tempX)*(CentrKachXex-tempX)+(CentrKachYex-tempY)*(CentrKachYex-tempY));
//say('CentrKachXex='+Floattostr(CentrKachXex)+' CentrKachYex='+Floattostr(CentrKachYex));
//say('tempX='+Floattostr(tempX)+' tempY='+Floattostr(tempY));
//say('Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(tempLenght));
tempZ:=BotCoordZ-ReadD(14);
if tempz<0 then tempZ:=tempz*(-1);
//say('TempZ='+inttostr(tempz));
//say('BotCoordZ='+inttostr(BotCoordZ));
//say('MobCoordZ='+inttostr(readd(14)));
if tempZ<=DeltaZ then begin
if (int(tempLenght)<Radius) then begin
//say('Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
//перебираем базу и ищем там моба который бежит
for i:=1 to max do begin
//если нашли Моба в базе, то коректируем его координаты на новые
if (MobBase[1,i]=ReadD(2)) and (CharID<>ReadD(2)) and (PetID<>ReadD(2)) and (CharBase[1,i]<>ReadD(2)) then begin //ObjectID
MobBase[2,i]:=ReadD(6); //x
MobBase[3,i]:=ReadD(10); //y
MobBase[4,i]:=ReadD(14); //z
//Ext массив
MobBaseExt[2,i]:=ReadD(6); //x
MobBaseExt[3,i]:=ReadD(10); //y
MobBaseExt[4,i]:=ReadD(14); //z
//say('Корректируем координаты Моба'+' ColvoMobs='+inttostr(colvomobs));
//say('>Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
AddMob:=false;
end;
end;
//иначе, перебираем базу, ищем свободную ячейку в ней и добавляем нового моба
for i:=1 to max do begin
if (MobBase[1,i]=0) and AddMob and (CharID<>ReadD(2)) and (PetID<>ReadD(2)) then begin
//запоминаем моба в свободную ячейку
MobBase[1,i]:=ReadD(2); //ObjectID
MobBase[2,i]:=ReadD(6); //x
MobBase[3,i]:=ReadD(10); //y
MobBase[4,i]:=ReadD(14); //z
//Ext массив
MobBaseExt[1,i]:=ReadD(2); //ObjectID
MobBaseExt[2,i]:=ReadD(6); //x
MobBaseExt[3,i]:=ReadD(10); //y
MobBaseExt[4,i]:=ReadD(14); //z
inc(colvomobs);
//colvomobs:=colvomobs+1;
say('Запоминаем координаты Моба'+' ColvoMobs='+inttostr(colvomobs));
//say('>Radius='+Floattostr(Radius)+' tempLenght='+Floattostr(int(tempLenght)));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
break;
end;
end;
end;
end;
end;
//****************************************************************************
//MagicSkillUse 48, Attack 05
if FromServer and (ConnectName=Name) and ((pck[1]=#$48) or (pck[1]=#$05)) then begin
if UnderAttack then exit; //сначало убъем одного
Attacker:=ReadD(2);
ObjectID:=ReadD(6);
if (Attacker<>ObjectID) and (CharID=ObjectID) then begin
UnderAttack:=true; //нас атакуют
needbackup:=false;
Say('Нас атакуют!');
TargetAttacker(Attacker);
end;
end;
//****************************************************************************
//если принят пакет Die
if FromServer and (ConnectName=Name) and (pck[1]=#$06) then begin
//ищем моба в базе
if (Attacker=ReadD(2)) then begin
UnderAttack:=false; //убили атакующего моба
//say('UnderAttack=false');
timer2.enabled:=true; //включаем отсчет времени
end;
for i:=1 to max do begin
//очишаем запись связанную с етим мобом
if (MobBase[1,i]=ReadD(2)) then begin
dec(colvomobs);
//say('Удаляем координаты Моба'+' ColvoMobs='+inttostr(colvomobs));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
MobBase[1,i]:=0; //ObjectID
MobBase[2,i]:=0; //x
MobBase[3,i]:=0; //y
MobBase[4,i]:=0; //z
//Ext массив
MobBaseExt[1,i]:=0;
MobBaseExt[2,i]:=0;
MobBaseExt[3,i]:=0;
MobBaseExt[4,i]:=0;
break;
end;
end;
end;
//****************************************************************************
//если принят пакет DeleteObject
if FromServer and (ConnectName=Name) and (pck[1]=#$12) then begin
//ищем моба в базе
//say('DeleteObject');
if (Attacker=ReadD(2)) then begin
UnderAttack:=false; //убили атакующего моба
//say('UnderAttack=false');
timer2.enabled:=true; //включаем отсчет времени
end;
for i:=1 to max do begin
//очишаем запись связанную с етим мобом
if (MobBase[1,i]=ReadD(2)) then begin
//say('Удаляем координаты Моба');
dec(colvomobs);
//say('Удаляем координаты Моба'+' colvomobs='+inttostr(colvomobs));
//say('ID='+inttostr(MobBase[1,i])+' X='+inttostr(MobBase[2,i])+' Y='+inttostr(MobBase[3,i])+' Z='+inttostr(MobBase[4,i]));
MobBase[1,i]:=0; //ObjectID
MobBase[2,i]:=0; //x
MobBase[3,i]:=0; //y
MobBase[4,i]:=0; //z
//Ext массив
MobBaseExt[1,i]:=0;
MobBaseExt[2,i]:=0;
MobBaseExt[3,i]:=0;
MobBaseExt[4,i]:=0;
break;
end;
end;
for i:=1 to max do begin
//если нашли в базе, то удаляем
if (CharBase[1,i]=ReadD(2)) then begin
CharBase[2,i]:=0; //x
CharBase[3,i]:=0; //y
CharBase[4,i]:=0; //z
//say('Удаляем координаты Игрока');
end;
end;
end;
//****************************************************************************
//ValidatePosition если принят пакет от клиента с моими кординатами то
if FromClient and (ConnectName=Name) and (pck[1]=#$48) then begin
//запоминаем мои координаты
BotCoordX:=ReadD(2);
BotCoordY:=ReadD(6);
BotCoordZ:=ReadD(10);
//ext
BotCoordXext:=ReadD(2);
BotCoordYext:=ReadD(6);
BotCoordZext:=ReadD(10);
//say('Запоминаем координаты Бота');
//say('Бот X='+inttostr(BotCoordX)+' Y='+inttostr(BotCoordY)+' Z='+inttostr(BotCoordZ));
//say('Бот Xext='+floattostr(BotCoordXext)+' Yext='+floattostr(BotCoordYext)+' Zext='+floattostr(BotCoordZext));
end;
//****************************************************************************
//если от сервака принят пакет с ИД и Координатами членов пати то
if FromServer and (ConnectName=Name) and (pck[1]=#$a7) then begin
//запоминаем ИД командира
CharID:=ReadD(6);
if scrready then exit
else begin
Say('Скрипт готов к работе. Запомнил ИД лидера');
scrready:=true;
end;
end;
//****************************************************************************
//если от сервака принят пакет с UserInfo
if FromServer and (ConnectName=Name) and (pck[1]=#$04) then begin
//Запоминаем собственный ИД
CharID:=ReadD(18);
if scrready then exit
else begin
Say('Скрипт готов к работе. Запомнил ИД лидера');
scrready:=true;
end;
end;
//****************************************************************************
//если от сервака принят пакет с PetInfo
if FromServer and (PetID=0) and (ConnectName=Name) and (pck[1]=#$b1) then PetID:=ReadD(6);
//****************************************************************************
//DropItem - выпала вещь
if FromServer and (ConnectName=Name) and (pck[1]=#$0C) then begin
//чужие вещи не берем
if (Attacker=ReadD(2)) then begin
timer1.enabled:=false; //выключаем бота
AddMob:=true;
//перебираем базу
for i:=1 to max do begin
//если нашли, то корректируем его координаты на новые
if (ItemBase[1,i]=ReadD(6)) then begin //ObjectID
ItemBase[2,i]:=ReadD(14); //x
ItemBase[3,i]:=ReadD(18); //y
ItemBase[4,i]:=ReadD(22); //z
AddMob:=false;
inc(itm);
NeedBackup:=true;
say('Корректируем данные по предмету');
end;
end;
//иначе, перебираем базу, ищем свободную ячейку в ней и добавляем
for i:=1 to max do begin
if (ItemBase[1,i]=0) then begin
//запоминаем в свободную ячейку
ItemBase[1,i]:=ReadD(6); //ObjectID
ItemBase[2,i]:=ReadD(14); //x
ItemBase[3,i]:=ReadD(18); //y
ItemBase[4,i]:=ReadD(22); //z
inc(itm);
NeedBackup:=true;
say('Добавили данные по предмету');
break;
end;
end;
end;
say('ColvoItm='+inttostr(itm));
end;
//****************************************************************************
//Пока отключил. Бежит сломя голову за тридевять земель, не обращая внимания что лежит рядом.
//To Do: Сделать проверку на расстояние.
//SpawnItem - выляется вещь
{if FromServer and (ConnectName=Name) and (pck[1]=#$0B) then begin
timer1.enabled:=false; //выключаем бота
AddMob:=true;
//перебираем базу
for i:=1 to max do begin
//если нашли, то корректируем его координаты на новые
if (ItemBase[1,i]=ReadD(2)) then begin //ObjectID
ItemBase[2,i]:=ReadD(10); //x
ItemBase[3,i]:=ReadD(14); //y
ItemBase[4,i]:=ReadD(18); //z
AddMob:=false;
inc(itm);
NeedBackup:=true;
say('Корректируем данные по предмету');
end;
//иначе, перебираем базу, ищем свободную ячейку в ней и добавляем
for i:=1 to max do begin
if (ItemBase[1,i]=0) and AddMob then begin
//запоминаем в свободную ячейку
ItemBase[1,i]:=ReadD(2); //ObjectID
ItemBase[2,i]:=ReadD(10); //x
ItemBase[3,i]:=ReadD(14); //y
ItemBase[4,i]:=ReadD(18); //z
inc(itm);
NeedBackup:=true;
say('Добавили данные по предмету');
break;
end;
end;
end;
say('ColvoItm='+inttostr(itm));
end;}
//****************************************************************************
if Wait(time1,2000) and NeedBackup and (underAttack=false) then ReqGetItem;
//****************************************************************************
//определяем реальность поднятия вещи
//GetItem
if FromServer and (ConnectName=Name) and (pck[1]=#$0D) then begin
//перебираем базу
for i:=1 to max do begin
//если нашли, то обнуляем
if (ItemBase[1,i]=ReadD(6)) then begin //ObjectID
ItemBase[1,i]:=0; //x
ItemBase[2,i]:=0; //x
ItemBase[3,i]:=0; //y
ItemBase[4,i]:=0; //z
dec(itm);
//say('Удаляем данные по предмету');
end;
end;
if itm=0 then begin
needbackup:=false;
timer1.enabled:=true;
end;
say('ColvoItm='+inttostr(itm));
end;
//****************************************************************************
if FromClient and (ConnectName=Name) and (pck[1]=#$1B) then begin
SocialID:=ReadD(2);
case SocialID of
//социальное действие Yes для начала
6: begin
//if CharID=0 then exit;
CentrKachX:=BotCoordX;
CentrKachY:=BotCoordY;
CentrKachXex:=BotCoordXext;
CentrKachYex:=BotCoordYext;
//say('Получили координаты центра');
say('X='+inttostr(BotCoordX)+' Y='+inttostr(BotCoordY));
timer1.enabled:=true;
Say('Команда Старт!!!');
exit;
end;
//социальное действие No для окончания
5: begin
//if CharID=0 then exit;
timer1.enabled:=false;
Say('Команда Стоп!!!');
exit;
end;
end;
end;
end.
|