Спасибо всем за замечание, вот вчерашний дописанный скрипт. В описаловке к скрипту все написано. Замечание:
- теперь можно управлять скрипом из других скриптов через чат.
- социальные действия отключены (если надо раскоментировать)
delphi Код:
///////////////////////////////////////////////////////////////// для: L2PacketHack by xkor // посл. редактирование: 14.05.2008, 15:03msk, alexsl // назначение: перемещение чара по заранее записаным маршруту(м) // // краткая инструкция: // // 1. прописать ник в MyNick // // - для записи пути в файл: // 1. встаем на исходную позицию // 2. в чат пишим "===rec test1" (test1 - или другое имя без пробелов) // 3. бежим куда нужно. (желательно много не кликать на одно и тоже место. все клики записываются в файл) // 4. в чат пишим "===save" // 5. все. теперь данные записаны на диск, согласно настройкам и под именем test1 указ. в п.п.2 // // - записываем требуемые пути с разными маршрутами и названиями // // - использование // 1. бег до последнего чекпоинта(при достижении скрипт завершает работу): // пишим в чат "===go test1" (test1 - название записанного маршрута) // 2. бег до первого чекпоинта (при достижении скрипт завершает работу): // пишим в чат "===back test1" (test1 - название записанного маршрута) // 3. для остановки скрипта при передвижении: пишим в чат "===stop" // // как работает?: при запуске бежит к ближайшему чекпоинту и следует согласно направлению// Использовались идеии, коды участников форума за, что спасибо ///////////////////////////////////////////////////////////////////// var// movement data
MovePath, // данные по которому мы будем двигатся в данный момент
RecordPath: TStringList; // данные для записи пути
RecordPathFileName: string; // название файла для записи
PointsCount: integer; // кол-во поинтов в процессе записи пути
SavePathEnabled: boolean; // флаг записи пути
MoveToPathEnabled: boolean; // флаг движения по пути
MoveToForward: boolean; // направление движения да-вперед, нет - назад
MoveStepIndex: integer; // текущ. чекпоинт (куды бежим сейчас)
MoveTimer: TTimer; //
old_X,old_Y,old_Z,old_time: integer;
myX,myY,myZ: integer; // наши статы
myID: integer;
myHP,myMP,myMaxHP,myMaxMP: integer;
const
MyNick = 'Мой ник';// <------------------------------
interlude = false;
debug = false;
// эта переменная указывает уничтожить пакет или нет если он обработан // может данные нужны для других скриптов
EraseCommandFromChat = true;
//*******************************************************
RecordFilesPath = 'c:\'; // путь где хранятся наши файлы
RecordPathName = 'recordmove'; // файл по умолчанию
RecordFileExt = '.txt';// расширение по умолчанию
RangeToCheckPoint = 150; // дистанция до чекпоинта при которой считается , что мы достигли оного
MoveTrigerDelay = 800; // срабатывание таймера на движение 0,8 сек
cmdPrefix = '===';// с этих символов начинается команда
cmdDlm = ' ';// разделитель параметров команды, параметры не должены содержать разделитель // команды в общий чат // пример
cmdRecordPath = 'rec'; // в общий чат "===rec giran1"
cmdSavePath = 'save'; // в общий чат "===save"
cmdMove = 'go'; // в общий чат "===go giran1"
cmdBack = 'back'; // в общий чат "===back giran1"
cmdStop = 'stop'; // останавливает следование по маршруту //******************************************************* procedure Init; //Вызывается при включении скрипта begin
MoveTimer := TTimer.Create(nil);
MoveTimer.Enabled := False;
MoveTimer.Interval := MoveTrigerDelay;
MoveTimer.OnTimer := @OnMove;
RecordPathFileName:='';
buf:=hstr('0F');
SendToServerEX(MyNick);
RecordPath:=TStringList.Create;
MovePath:=TStringList.Create;
end;
procedure Free; //Вызывается при выключении скрипта beginif RecordPath<>nil thentry
RecordPath.Free;
except
debugmsg('error free RecordPath');
end;
if MovePath<>nil thentry
MovePath.Free;
except
debugmsg('error free MovePath');
end;
end;
procedure debugmsg(s: string);
beginif debug then
SendMsg(s);
end;
function GetValue(ValName: string): string;
begin
result:=RecordPath.Values[ValName];
end;
procedure SetValue(ValName: string; Value: string);
begin
RecordPath.Values[ValName]:=Value;
end;
procedure StartRecord;
beginif SavePathEnabled thenexit;
if MoveToPathEnabled thenbegin
SendMsg('Во время следования по маршруту запись не возможна');
exit;
end;
RecordPath.Clear;
PointsCount:=0;
SendMsg('Начата запись маршрута');
SavePathEnabled := Trueend;
procedure StopRecord;
beginifnot SavePathEnabled thenexit;
// записываем
RecordPath.SaveToFile(GetRecordFileName);
SendMsg('Запись маршрута завершена');
SavePathEnabled := False;
end;
function GetRecordFileName: string;
begin
result:=RecordFilesPath+RecordPathFileName+RecordFileExt;
end;
procedure SendMsg(msg:string); // отправка системных сообщений клиенту begin
buf:=#$4A;
WriteD(0);
WriteD(10);
WriteS('');
WriteS(msg);
SendToClientEx(MyNick);
end;
procedure ParseMoveClient;
var
i,x,y,z: integer; s: string;
beginifnot SavePathEnabled thenexit;
i:=2;
x:=readd(i);
y:=readd(i);
z:=readd(i);
inc(PointsCount);
s:='|'+inttostr(x)+'|'+inttostr(y)+'|'+inttostr(z)+'|';
RecordPath.Add(s);
SendMsg('добавлен чекпоинт № '+inttostr(PointsCount));
end;
function delta(xpos1, ypos1, xpos2, ypos2:extended):integer; //возвращает переменную rezu которая является растоянием между 2 точками var
dx,dy,summa: extended;
begintry
dx:= xpos1-xpos2;
dy:= ypos1-ypos2;
summa:= dx*dx+dy*dy;
if summa = 0then result:= 0else result:= Round(sqrt(summa));
debugmsg('delta='+inttostr(result));
except
debugmsg('error in delta');
end;
end;
function GetMinCheckPoint(PointsList: TStringList): integer;
var
i,m,min_dist: integer;
s: string;
x,y,z: integer;
begin
result:=-1;
min_dist:=-1;
// проверка на наличие маршрута if PointsList.Count=0thenbeginexit;
MoveTimer.Enabled:=False;
MoveToPathEnabled:=False;
SendMsg('Нет данных по маршруту');
exit;
end;
tryfor i:=0to PointsList.count-1dobegin
s:=PointsList[i];
y:=ExtractValue(s,2);
x:=ExtractValue(s,1);
debugMsg(s+' x:='+inttostr(x)+' y:='+inttostr(y));
m:=delta(x,y,myx,myy);
if m>0thenbeginif(result=-1)thenbegin
min_dist:=m;
result:=i;
endelseif m<min_dist thenbegin
min_dist:=m;
result:=i;
end;
end;
end;
except
debugMsg('error in GetMinCheckPoint');
end;//try end;
procedure GoToPath(ToForward: boolean);
var
x,y,z,i: integer;
s: string;
begin
MoveToPathEnabled:= not MoveToPathEnabled;
MoveToForward:=ToForward;
ifnot MoveToPathEnabled thenbegin
MoveTimer.Enabled:=False;
SendMsg('Следование по маршруту остановлено');
exit;
end;
// // предположительно путь уже прописан в MovePath //
SendMsg('Пробуем выйти на путь...');
// сперва идем к ближайшему чекпоинту
i:= GetMinCheckPoint(MovePath);
if i<0thenbegin
SendMsg('чекпоинт не найден');
MoveToPathEnabled:=False;
endelsebegin
SendMsg('найден ближайший чекпоинт бежим туды');
MoveToPathEnabled:=True;
MoveStepIndex:=i;
if debug then
SendMsg('checkpoint #'+inttostr(i));
s:=MovePath[MoveStepIndex];
x:=ExtractValue(s,1);
y:=ExtractValue(s,2);
z:=ExtractValue(s,3);
if(old_x<>x)and(old_y<>y)and(old_z<>z)thenbegin
MoveTo(x,y,z);
old_x:=x;
old_y:=y;
old_z:=z;
old_time:=0;
end;
end;
MoveTimer.Enabled:=True;
end;
//***************************************************************procedure OnMove(Sender: TObject);
var
x,y,z: integer; s: string;
begininc(old_time);// счетчик, сколько тиков прошло с последнего клика. исп. при следованию по маршрутуifnot MoveToPathEnabled thenbegintry
TTimer(Sender).Enabled:=False;
exceptend;
SendMsg('Движение остановлено');
exit;
end;
// возможно мы пали смертью храбрых, то не дергаемся покаif myHP<=0thenbegin
sendmsg('Die');
MoveToPathEnabled:=False;
exit;
end;
debugmsg('hp:'+inttostr(myhp));
try// проверяем на существ. объекта // при отладке всякое может быть
MovePath.Count;
except
TTimer(Sender).Enabled:=False;
exit;
end;
s:=MovePath[MoveStepIndex];
x:=ExtractValue(s,1);
y:=ExtractValue(s,2);
z:=ExtractValue(s,3);
if PosInRange(x,y,z,RangeToCheckPoint)thenbeginif MoveToForward thenbeginif MoveStepIndex=MovePath.Count-1thenbegin
MoveToPathEnabled:=False;
SendMsg('Мы по идее в конечной точке');
exit;
endelsebegininc(MoveStepIndex);
end;
endelsebeginif MoveStepIndex>0thendec(MoveStepIndex)elsebegin
MoveToPathEnabled:=False;
SendMsg('Мы по идее в начальной точке');
exit;
end;
end;
// мы достигли чекпоинта идем далее
SendMsg('бежим к #'+inttostr(MoveStepIndex));
s:=MovePath[MoveStepIndex];
x:=ExtractValue(s,1);
y:=ExtractValue(s,2);
z:=ExtractValue(s,3);
MoveTo(x,y,z);
end;
end;
function ExtractValue(sData: string;nIndex: integer): integer;
var
s: string;
i,j: integer;
begin
i:=0;j:=0;s:='';
s:=sData;
while j<nIndex dobegin
i:=pos('|',S);
if i>=0thenbegin
s:=copy(s,i+1,length(s)-i);
inc(j);
endelsebreak;
end;
i:=pos('|',s);
if i>=0then
s:=copy(s,1,i-1);
try
result:=strtoint(s);
exceptend;
end;
//****************************************************************** //Bot by Skymanrus //modified by NLObP специально для Владера, моего сына! //ПЕРЕМЕЩЕНИЕ: //Идти в точку с координатами 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(MyX); //откуда
WriteD(MyY);
WriteD(MyZ);
WriteD(1); //используем 1-мышь 0-клавиатура
SendToServerEx(MyNick);
end;
//Ориентация на местности: //Проверка находится ли заданная точка в пределах досягаемости. Если да, то выполняется кусок скрипта в фигурных скобках {}. function PosInRange(targetx,targety,targetz,distanciya:integer):boolean;
beginif delta(targetx, targety, MyX, MyY)<=distanciya
then result:=trueelse result:=false;
end;
procedure UserInfo; // обновление донных о себе var
i:word;
begin
MyID:=ReadD(18);
MyX:=ReadD(2);
MyY:=ReadD(6);
MyZ:=ReadD(10);
i:=22;
ReadS(i);
if interlude then i:=i+48else i:=i+44;
MyMaxHP:=ReadD(i);
MyHP:=ReadD(i);
MyMaxMP:=ReadD(i); // чисто информативно
MyMP:=ReadD(i);
end;
procedure StatusUpdate; // обновление данных о себе var
i: integer;
beginfor i:=0to ReadD(6)-1docase pck[i*8+10] of
#$09: MyHP:=ReadD(i*8+14);
#$0A: MyMaxHP:=ReadD(i*8+14);
#$0B: MyMP:=ReadD(i*8+14);
#$0C: MyMaxMP:=ReadD(i*8+14);
end;
end;
//*************************************************************** procedure OnConnect(WithClient: Boolean); //Вызывается при установке соединения beginend;
procedure OnDisonnect(WithClient: Boolean); //Вызывается при потере соединения beginend;
function iif(Bool: Boolean;aTrue: variant; aFalse: variant): variant;
beginif Bool then
result:=aTrue
else
result:=aFalse;
end;
function ParseCmd(cmd: string):boolean;
var
s: string;
i,j,k: integer;
params: array[0..9] ofstring; // до 10 параметров, должно хватить begin
result:=False;
try
j:=-1;
i:=pos(cmdPrefix,trim(cmd));
if i=0thenexit;
debugmsg('start ParseCmd: idx:'+inttostr(i)+' cmd: '+cmd);
result:=true;
k:=length(cmdPrefix);
s:=trim(lowercase(cmd));
s:=trim(copy(s,i+k,length(cmd)-i));
debugmsg('trim:'+s);
repeatinc(j);
k:=pos(cmdDlm,s);
if k>0thenbegin
params[j]:=copy(s,1,k-1);
// s:=copy(s,k+length(cmdDlm),length(s)-k-length(cmdDlm));
s:=trim(copy(s,k+length(cmdDlm),length(s)-k));
debugmsg('extract idx:'+inttostr(j) +' param:'+params[j]);
endelsebegin
params[j]:=s;
debugmsg('parm is one');
end;
untilpos(cmdDlm,S)=0;
if j>-1thenbegininc(j);
params[j]:=s;
debugmsg('extract idx:'+inttostr(j) +' param:'+params[j]);
end;
if j=-1thenexit;
//******************************************************* // пропарсили команду // теперь выполняем //******************************************************* if params[0]=cmdRecordPath thenbeginif params[1]<>''then
RecordPathFileName:=params[1]
else
RecordPathFileName:=RecordPathName;
StartRecord;
endelseif params[0]=cmdSavePath thenbegin
StopRecord;
endelseif params[0]=cmdMove thenbeginif params[1]=''thenbegin
SendMsg('хз куда бежать, укажите имя');
exit;
end;
try
MovePath.LoadFromFile(RecordFilesPath+params[1]+RecordFileExt);
except
SendMsg('файл пути не найден');
exit;
end;
GoToPath(true);
endelseif params[0]=cmdBack thenbeginif params[1]=''thenbegin
SendMsg('хз куда бежать, укажите имя');
exit;
end;
try
MovePath.LoadFromFile(RecordFilesPath+params[1]+RecordFileExt);
except
SendMsg('файл пути не найден');
exit;
end;
GoToPath(false);
endelseif(params[0]=cmdStop)and MoveToPathEnabled then
MoveToPathEnabled:=False;
except
debugmsg('error in ParseCmd,params='+cmd);
end;
end;
//основная часть скрипта //вызывается при приходе каждого пакета если скрипт включен var
i: integer;
beginif FromClient and(ConnectName=MyNick)thencase pck[1] of{
#$1B: // social
case pck[2] of
#$06: StartRecord; //Yes
#$05: StopRecord;//No
#$04: begin GoToPath(true); pck:=''; end;
end; //case
}
#$01: // move
ParseMoveClient;
#$38: // say2 // если это команда и она обработана и надо очистить чат if ParseCmd(ReadS(2))and EraseCommandFromChat then
pck:='';// kill packet
#$48:
begin
myx:=ReadD(2);
myY:=ReadD(6);
myZ:=ReadD(10);
end;
end; // case if FromServer and(ConnectName=MyNick)thencase pck[1] of
#$04: UserInfo;
#$0E: StatusUpdate;
end; // case end.
Добавлено через 48 минут
Цитата:
Надо попробовать развить скрипт в разрезе ASTAR (A*)
интересная идея, гдето видел геодату от явы сервера, вечерком посмотрю может можно будет прикрутить. ну а на счет оценки стоимости передвижения ... ммм .. какие идеи? вариант: бот камикадзе, бегает туды сюды тыкается или самому отмечать чекпоинты или если есть в геодате инфа о проходимости того или иного участка юзать ее.
Последний раз редактировалось alexsl, 16.05.2008 в 15:01.