PDA

Просмотр полной версии : скрипт для убегания от персонажа


Breadfan
06.12.2010, 01:33
Практическое применение скрипта - неизвестно (так сказать - l'art pour l'art) :) Но весело бегает :) IL

const
name='Sonja'; //кто убегает
ContrName='Lorreina';//от кого (контролируемый)
var
Mov:TTimer;
MyX,MyY,MyZ:integer;
ContrOID, ContrX, ContrY, ContrZ:integer;//координаты контролируемого перса
ToX, ToY, ToZ:integer;//куда скочет
MToX, MToY, MToZ:integer;//куда скакать боту
x1, y1,z1:integer;//дельта
dx,dy,dz:extended;//еще одна дельта, но за еденицу времени :)
virtX,virtY,virtZ:integer;//проверочные координаты
j:integer;//сдвиг в чаринфо
cosx,siny,path:extended;//косинус х\у и путь между точками Contr-To
rspeed, timetorun,step:integer;//скорость персонажа и расчетное время на путь
mult:extended;//множитель скорости передвижения
radius:integer;//радиус допустимого приближения.
procedure Init;
begin
ContrOID:=0;
ContrX:=0; ToX:=0; MToX:=0;
ContrY:=0; ToY:=0; MToX:=0;
ContrZ:=0; ToZ:=0; MToZ:=0;
step:=0;
radius:=300;
Mov:=TTimer.Create(nil);
Mov.OnTimer:=@Schet;
Mov.enabled:=false;
Mov.interval:=1000
end;
Procedure Schet;
begin
if (step<timetorun) then begin
virtX:=virtX+int(dx);
virtY:=virtY+int(dy);
virtZ:=virtZ+int(dz);
Sendmsg('virtX: '+inttostr(virtX)+' virtY: '+inttostr(virtY)+'virtZ: '+inttostr(virtZ));
inc(step);
end else begin
step:=0;
Mov.enabled:=false;
Sendmsg('Прибежали?');
end;
if (sqrt((virtX-MyX)*(virtX-MyX)+(virtY-MyY)*(virtY-MyY)+(virtZ-MyZ)*(virtZ-MyZ))<radius) then begin
//ф-ла расстояния между точками
SendMsg('ALARM!');
cosx:=(MyX-virtX)/(sqrt((virtX-MyX)*(virtX-MyX)+(virtY-MyY)*(virtY-MyY)));
siny:=(MyY-virtY)/(sqrt((virtX-MyX)*(virtX-MyX)+(virtY-MyY)*(virtY-MyY)));
MToX:=int(radius*siny)+MyX;//sin и cos поменяны местами
MToY:=int(radius*cosx)+MyY;//вроде так он должен убегать перпендикулярно траектории вражины
buf:=#$01;
WriteD(MToX);
WriteD(MToY);
WriteD(MyZ);
WriteD(MyX);
WriteD(MyY);
WriteD(MyZ);
WriteD(1);
Sendmsg(strtohex(buf));
Sendtoserverex(name);
end;
end;
procedure Free;
begin
Mov.free;
end;
begin
if fromserver and (connectname=name) then begin
if (pck[1]=#$03) and (ReadS(22)=ContrName) then begin
ContrOID:=ReadD(18);
ContrX:=ReadD(2);
ContrY:=ReadD(6);
ContrZ:=ReadD(10);
virtX:=ContrX;
virtY:=ContrY;
virtZ:=ContrZ;
j:=22;
ReadS(j);
j:=j+15*4+48+6*4;//смещение для считывания скорости перса
rspeed:=ReadD(j);//считываем "чистую" скорость
mult:=ReadF(j+7*4);//считываем множитель скорости
rspeed:=int(rspeed*mult);//пересчитываем скорость передвижения
Sendmsg('Find player '+ContrName+' OID:'+inttostr(ContrOID)+' X:'+inttostr(ContrX)+' Y:'+inttostr(ContrY)+' Z:'+inttostr(ContrZ));
Sendmsg('Speed: '+inttostr(rspeed));
end;
if (pck[1]=#$01) and (ReadD(2)=ContrOID) then begin
ToX:=ReadD(6);
ToY:=ReadD(10);
ToZ:=ReadD(14);
ContrX:=ReadD(18);
ContrY:=ReadD(22);
ContrZ:=ReadD(26);
virtX:=ContrX;
virtY:=ContrY;
virtZ:=ContrZ;
x1:=ToX-ContrX;
y1:=ToY-ContrY;
z1:=ToZ-ContrZ;
path:=Sqrt(x1*x1+y1*y1+z1*z1);
//патч\рспид - время на путь
timetorun:=int(path/rspeed);
if (path<>0) and (rspeed<>0) then begin
dx:=(x1/(path/rspeed));
dy:=(y1/(path/rspeed));
dz:=(z1/(path/rspeed));
step:=0;
Sendmsg('Timer - on!');
Mov.enabled:=True;
end;
Sendmsg('Player '+Contrname+' move to X:'+inttostr(ToX)+' Y:'+inttostr(ToY)+' Z:'+inttostr(ToZ));
Sendmsg('Length path: '+VarToStr(path));
Sendmsg('dx: '+vartostr(dx)+'dy: '+vartostr(dy)+'dz: '+vartostr(dz));
end;
if (pck[1]=#$60) and (ReadD(2)=ContrOID) then begin
ToX:=ReadD(14);
ToY:=ReadD(18);
ToZ:=ReadD(22);
Sendmsg('Player '+Contrname+' move to target in X:'+inttostr(ToX)+' Y:'+inttostr(ToY)+' Z:'+inttostr(ToZ));
end;
end;
if fromclient and (connectname=name) then begin
if (pck[1]=#$48) then begin
MyX:=ReadD(2);
MyY:=ReadD(6);
MyZ:=ReadD(10);
end;
end;
end.

Принцип: если в поле зрения попадает КонтрНейм - расчитывается путь его движения, и если он проходит от бота менее чем в "радиус" единиц, то бот (теоретически) ломится в сторону перпендикулярную вектору движения КонтрНейма, как-то так :) кстати - по причине сырости скрипта - не обрабатывает MoveToPawn. Еще надо вставить проверку на пересечение прямой движения КонтрНейма вектором движения бота - чтобы бот не ломанулся ненароком наперерез.