PDA

Просмотр полной версии : Active Follow


sinles
25.01.2011, 09:45
Формула вычисления точки на векторе:
a + t*(b-a)
где а - начальная точка; b - конечная; t - коэффициент от -1 до 1.
Позволит в скрипте боту следовать не на рандомные координаты вокруг цели, а ему за спину.
Есть проблема с его отставанием при пробежке на большую дистанцию. То есть бот будет не добегать до вас на 10% (для большой дистанции это может быть 300 ярдов)

Вот собственно функция для организации следования:

procedure TargetMovedTo(tx, ty, tz : integer);
var nX, nY, nZ : integer;
begin
if not follow then exit;
if delta(MyX,MyY,tx,ty) < 150 then exit;
nX := Round(tx + dist * (MyX - tx));
nY := Round(ty + dist * (MyY - ty));
MoveTo(nx, ny, tz);
end;
Её нужно вызывать каждый раз когда мы перехватили координаты цели за которой следуем.

Вот тестовый скрипт, который вешает чара под ником Name за тем кто напишет в чат go
program Follow;
const
Name='Superus';
TargetName='BigBoobs';
dist=0.2;

low=-1;
var
follow: boolean;
myX,myY,myZ: integer; //наши статы
MyOID, TargetOID: integer;

procedure Init; //Вызывается при включении скрипта
begin
follow := false;
end;

procedure Free; //Вызывается при выключении скрипта
begin
end;


procedure msg(msg:string); //отправка системных сообщений клиенту
begin
buf:=#$4A;
WriteD(0);
WriteD(10);
WriteS('');
WriteS(msg);
SendToClientEx(Name);
end;

procedure MoveTo(TargetX,TargetY,TargetZ:integer);
begin
//01=MoveBackwardToLocation:d(targetX)d(targetY)d(ta rgetZ)d(originX)d(originY)d(originZ)d(moveByMouse)
buf:=#$0F;
WriteD(targetx); //куда
WriteD(targety);
WriteD(targetz);
WriteD(MyX); //откуда
WriteD(MyY);
WriteD(MyZ);
WriteD(1); //используем 1-мышь 0-клавиатура
SendToServerEx(Name);
end;

procedure TargetMovedTo(tx, ty, tz : integer);
var nX, nY, nZ : integer;
begin
if not follow then exit;
if delta(myx,myy,tx,ty) < 150 then exit;
nX := Round(tx + dist * (MyX - tx));
nY := Round(ty + dist * (MyY - ty));
MoveTo(nx, ny, tz);

end;

//......................................

function delta(xpos1, ypos1, xpos2, ypos2:extended):integer;
var
dx,dy,summa: extended;
begin

dx:= xpos1-xpos2;
dy:= ypos1-ypos2;
summa:= dx*dx+dy*dy;
if summa = 0 then result:= 0 else result:= Round(sqrt(summa));

end;


//************************************************** *************
//обработка сообщений
//s32=UserInfo:d(X)d(Y)d(Z)d(Heading)d(ObjectID)...
procedure UserInfo; //обновление данных о себе
var
i:word;
begin
MyOID:=ReadD(18);
MyX:=ReadD(2);
MyY:=ReadD(6);
MyZ:=ReadD(10);
end;

//s31=CharInfo:d(X)d(Y)d(Z)d(Heading)d(ObjectID)...
procedure CharInfo();
var
j, toid: integer;
begin
if TargetName=ReadS(22) then
begin
TargetOID := ReadD(18);
TargetMovedTo(ReadD(2),ReadD(6),ReadD(10));
end;
end;

procedure CharMove();
var
j, toid: integer;
begin
if TargetOID=ReadD(2) then
begin
TargetMovedTo(ReadD(6),ReadD(10),ReadD(14));
end;
end;

procedure OnChatMsg();
var
j, chatID, playerID: integer;
playerName, Text: string;
begin

if ReadD(6)=3 then begin
j := 10;
playerName:=ReadS(j);
Text:=ReadS(j);
if (Text='go') or (Text='го') then
begin
TargetOID := ReadD(2);
follow := true;
msg('asd');
end;

end;
end;
//......................................

//основная часть скрипта
//вызывается при приходе каждого пакета если скрипт включен
begin
//не обрабатываем пустые пакеты
if pck='' then exit;
//************************************************** **************************
//серверные пакеты
if (ConnectName=Name) and FromServer then
case pck[1] of

#$32: UserInfo;
#$31: CharInfo;
#$4A: OnChatMsg;
#$2F: CharMove;

end;
//************************************************** **************************
//клиентские пакеты
if (ConnectName=Name) and FromClient then
case pck[1] of
//34=RequestSocialAction:d(Action:Get.Func09)
#$34: begin

end;
#$59:
begin
myX:=ReadD(2);
myY:=ReadD(6);
myZ:=ReadD(10);
end;
end;
if (ConnectName=TargetName) and FromClient then
case pck[1] of
//34=RequestSocialAction:d(Action:Get.Func09)
#$34: begin

end;
#$59:
begin
TargetMovedTo(ReadD(2),ReadD(6),ReadD(10));
end;
end;
end.

supernewbie
25.01.2011, 13:49
я бы на вашем месте координаты считал сам, а не юзал валидейт. это раз.
а во-вторых, попробовал бы убрать проверку на дистанцию, и в третьих, попробовал бы nX := Round(tx + dist * (MyX - tx)); заменить на
Round(tx + (((MyX - tx) / delta(MyX,MyY,tx,ty))*1))
вместо 1 пишите сколько надо прибавлять

dyh9l
25.01.2011, 13:50
[HIGHLIGHT="DELPHI" ][ /HIGHLIGHT] - на будущие, а если это и в правду скрипт бегания за спиной, то огромное тебе спс, иду тестить :)

supernewbie
25.01.2011, 13:51
и это ничерта не скрипт беганья за спиной, это скрипт бежания туда же куда бежит ведущий, но чуть-чуть недобегая до туда :D
PS проще говоря, если перс развернется, то мы не побежим за спину)

dyh9l
25.01.2011, 13:52
спина не зад? блин, он еще и под Грацию

sinles
25.01.2011, 20:41
я не про скрипт в целом тему создавал, реализация всего что лежит вне вычислений может быть какой угодно, простой или сложной.

спасибо supernewbie он предложил более правильный вариант подсчета.