Forum in READ ONLY mode! All questions and discussions on Discord official server, invite link: https://discord.gg/VxsGzJ7

Ходилка SomeBody.

Only working scripts
Mirage
Novice
Novice
Posts: 90
Joined: 18.07.2009 19:41

Post by Mirage »

Данная ходилка не работает (почемуто) на RC4-RC5, и не умеет бегать. А так ничетак. на RC3 все суперско.
RaTaMaHaTTa
Novice
Novice
Posts: 89
Joined: 16.06.2008 12:22
Location: <||TORCHKI||>
Contact:

Post by RaTaMaHaTTa »

Mirage wrote:Данная ходилка не работает (почемуто) на RC4-RC5, и не умеет бегать. А так ничетак. на RC3 все суперско.
Уху ) В последней версии вроде своя ходилка для которой нужны мулы. Могу ошибатся ибо пользуюсь Rc3.
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Post by grundick »

Mirage wrote:Данная ходилка не работает (почемуто) на RC4-RC5, и не умеет бегать. А так ничетак. на RC3 все суперско.
Может быть это связано с тем, что теперь step это функция, а не процедура?
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Post by grundick »

Вот вам его ходилка для RC4.
Тестите, критикуйте )
Есть одно но! Теперь не используется CheckFlow. у разных шардов разные системные сообщения при сейве, поэтоу не считаю целесообразным её подключать. Если я не прав - исправляюсь )

Не забываем про настройку шарда Check Diagonal Move! Важный параметр. Про него можете прочесть в разделе FAQ / Несколько слов о поиске пути.

Для самых ленивых напишу.
move идёт до цели с учётом таймаута. Изначально рассчитывается прямое расстояние до цели. Соответственно считается что чар совершит такое кол-во шагов. На каждый шаг выделяется время. (Сейчас это 3 сек, реально нужно подстраивать под условия) . Итого чару даётся времени = (кол-во шагов)*(время одного шага). Конечно это очень приближённый подсчет необходимого таймаута, потому что ходилка реально "не знает" длины пути. Тем не менее ,если время вышло, а цель не достигнута, move прекращает работу с сообщением 'Move: Time moved out!'
Функция _move тупо зацикливает работу функции move. Вот и всё различие.

Code: Select all

// написал Somebody. ICQ: 475728522 e-mail: [email protected]

// Реализация алгоритма "надёжной трассировки"
// http://pmg.org.ru/ai/stout.htm#robust_trace

const 
FMoveArrMax = 300; // ставь здесь больше, если твой чар ходит на дистанции больше 13 тайлов или вокруг чара очень много препятствий. Если препятствий на пути мало, то можно оставить как есть. 
var 
PrognosisX, PrognosisY, FMoveArrCount : integer; 
FMoveArr : array [1..FMoveArrMax] of array [1..2] of smallint; 

procedure LocalWaitConnection(WaitTime : Integer);
begin
if Connected then Exit;
while not Connected do Wait(1000);
{WaitTime - Waiting After Connected}
wait(WaitTime);
end;

Function Abs(A: integer): integer;
Begin
If A>=0 then result:=A 
Else result:=0-A;
End;

function SetDirection(x, y : integer) : integer; 
var
   MyX,MyY,DiffX,DiffY,GoDir: integer;
Begin
MyX:=GetX(self);
MyY:=GetY(self);
DiffX:=Abs(MyX-x);
DiffY:=Abs(MyY-y);

if (DiffX/(DiffY+0.1))>=2 then 
   begin
   if (MyX>X) then 
      GoDir:=6 
   else 
      GoDir:=2; 
   end  
else 
   
   if (DiffY/(DiffX+0.1))>=2 then 
      begin
      if (MyY>Y) then 
         GoDir:=0 
      else 
         GoDir:=4;
      end  
   else 
        
      if (MyX>X) and (MyY>Y) then  GoDir:=7
      else 

        if (MyX>X) and (MyY<Y) then  GoDir:=5 
        else 

           if (MyX<X) and (MyY>Y) then  GoDir:=1 
           else 

             if (MyX<X) and (MyY<Y) then  GoDir:=3; 
             
result:=GoDir;
end;


procedure CalcPrognosis(Dir : integer); 
begin 
   if (Dir = 1) or (Dir = 2) or (Dir = 3) then PrognosisX := GetX(self) + 1; 
   if (Dir = 5) or (Dir = 6) or (Dir = 7) then PrognosisX := GetX(self) - 1; 
   if (Dir = 0) or (Dir = 4) then PrognosisX := GetX(self); 

   if (Dir = 3) or (Dir = 4) or (Dir = 5) then PrognosisY := GetY(self) + 1; 
   if (Dir = 7) or (Dir = 0) or (Dir = 1) then PrognosisY := GetY(self) - 1; 
   if (Dir = 2) or (Dir = 6) then PrognosisY := GetY(self); 
end; 

function TryToMove(Direction : integer; RunFlag : boolean) : boolean; 
var 
  StepResult : byte;

begin 
   result:=false;
   wait(100);
   localWaitConnection(1000);     
   //While Not CheckLag(50) do Wait(500);   // checkLag не пашет!!! Визитера бить!!
 
   
   if IsWorldCellPassable(getX(self),getY(self),PrognosisX,PrognosisY,WorldNum,getZ(self)) then 
      begin
      if GetDirection(self) <> Direction then Step(Direction, RunFlag); 
      StepResult:=Step(Direction,RunFlag);
      If (StepResult=5) OR (StepResult=1) then wait(5000);
      If StepResult=7 then result:=true;
      end;
   
   
end; 

// available StepResult
// 0 - Unknown Error
// 1 - Mover: Resync is pending, ignoring.
// 2 - Mover: Step buffer overflow, Ignoring
// 3 - Mover: Client Canceled. Point not Passable.
// 4 - Mover: Move timeout.
// 5 - Mover: MoveReject
// 6 - Mover: Client Check OK, send move request
// 7 - Mover: Server Check OK, move request accepted

function WrongMove(x, y : integer) : boolean; 
var 
i : integer; 
begin 
   result := false; 
   if FMoveArrCount = 0 then exit; 
   for i := 1 to FMoveArrCount do 
      begin 
      if (x = FMoveArr[i][1]) and (y = FMoveArr[i][2]) then 
         begin 
         result := true; 
         exit; 
         end; 
      end; 
end; 


function Min(x,y: integer): integer;
begin
 if x>y then Result:=y else Result:=x;
end;

function HEst(x,y: integer): integer;
var dx,dy,Ddx : integer;
begin
  dx:= GetX(self)-x;
  dy:= GetY(self)-y;
  Ddx:= dx-dy;
  If dx<0 then dx:=0-dx;
  If dy<0 then dy:=0-dy;
  If Ddx<0 then Ddx:=0-Ddx;
  Result:= min(dx,dy)+Ddx;
end;

procedure SetWrongMove(x, y : integer); 
begin 
   if FMoveArrCount>298 then FMoveArrCount:=0;  // обнуление массива непроходимых тайлов
   FMoveArrCount := FMoveArrCount + 1; 
   FMoveArr[FMoveArrCount][1] := x; 
   FMoveArr[FMoveArrCount][2] := y; 
end; 

function RewindDir(Dir, c : integer) : integer; 
begin 
   result := Dir + c; 
   if result < 0 then result := result + 8; 
   if result > 7 then result := result - 8; 
end; 

function Move(x, y, tolerance : integer; RunFlag: boolean) : boolean; 
var 
Dir, Dist, lastX, lastY, t, i, timeout : integer; 
begin 
   FMoveArrCount := 0; 
   Dist := HEst(x, y); 
   timeout := Dist * 3000; // 3 секунды времени на шаг 
   t := timer; 
   while true do 
      begin 
      Dist := HEst(x, y); 
      if Dist <= tolerance then // пришёл 
         begin 
         result := true; 
         exit; 
      end; 
      if timer - t > timeout then // провал по таймауту 
      begin 
         AddToSystemJournal('Move: Time moved out!'); 
         result := false; 
         exit; 
      end; 
      Dir := SetDirection(x, y); 
      CalcPrognosis(Dir); 
      if WrongMove(PrognosisX, PrognosisY) then 
         begin 
         for i := 1 to 7 do 
            begin 
            Dir := RewindDir(Dir, 1); 
            CalcPrognosis(Dir); 
            if not WrongMove(PrognosisX, PrognosisY) then break; 
            end; 
      if i = 8 then 
         begin 
         AddToSystemJournal('Move: Cannot move'); 
         result := false; 
         exit; 
         end; 
      end; 
     // timeout := timeout + CheckFlow; 
      lastX := GetX(self); lastY := GetY(self); 
      if TryToMove(Dir, RunFlag) then SetWrongMove(lastX, lastY) // отсюда чар пришёл 
      else SetWrongMove(PrognosisX, PrognosisY); 
      end; 
end; 

procedure _move(x, y, tolerance : integer; RunFlag : boolean); 
begin 
while not Move(x, y, tolerance, RunFlag) do wait(100); 
end;
PS: Кстати, здесь реализован алгоритм обычной трассировки, а не надёжной, как написал Somebody.
Post Reply