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

Простая ходилка для версий ДО RC3

Only working scripts
Post Reply
Beren
Novice
Novice
Posts: 108
Joined: 08.09.2008 1:07

Простая ходилка для версий ДО RC3

Post by Beren »

Простая ходилка для стелса версий ДО RC3 с возможностью обхода деревьев, камней и прочих мелких препятствий. Использовалась в основном что бы бегать по лесу. Не застревает в П-образных тупиках. Легко зацикливается в углах.
move_v0_1.inc

Code: Select all

//////////////////////////////////////////////////////////////////////////////////////////////
//                move_v0_2.inc    11.09.2008                                               //
//    crafted by SevenAmber. e-mail: [email protected]                                   //
// алгоритм прохода к указанной точке с обходом небольших препятствий //
/////////////////////////////////////////////////////////////////////////////////////////////
type
  Dim8= Array[0..8] of integer;
  T_Dir_XY=record
   x:integer;
   y:integer;
  end;

var
 Co_ord_X,Co_ord_Y: Array of integer;
 Dir_Ch:array of string;
 revDir:dim8;
 IsInit:boolean;
    
Const
 N=0;// North
 NE=1;//NorthEast
 E=2;//East
 SE=3;//SouthEeast
 S=4;//South
 SW=5;//SouthWest
 W=6;//West
 NW=7;//NorthWest
 SLF=8;//self
 
Procedure Init_GoXY; // инициализация
begin
  Dir_Ch:=['N','NE','E','SE','S','SW','W','NW','SLF'];
  Co_ord_X:=[0,1,1,1,0,-1,-1,-1,0];
  Co_ord_Y:=[-1,-1,0,1,1,1,0,-1,0];
  revDir[N]:=S;revDir[S]:=N;revDir[W]:=E; revDir[E]:=W;
  revDir[NW]:=SE;revDir[SE]:=NW;revDir[NE]:=SW; revDir[SW]:=NE;
  revDir[SLF]:=SLF;
  IsInit:=true;
end;

function encode_dir(direction:integer):T_Dir_XY; // из направления получаем координаты
var
 TempDir:T_Dir_XY;
begin 
   TempDir.X:=GetX(self)+Co_ord_X[direction];
   TempDir.Y:=GetY(self)+Co_ord_Y[direction];
   Result:=TempDir;
end;

function CrdToString(sx,sy:integer):string;// координаты в строку типа <X,Y>
begin
 Result:='<'+IntToStr(sx)+','+IntToStr(sy)+'>'
end;

function DirToStr(direction:integer):string;// направление в строку типа <X,Y>
var
 TempDir:T_Dir_XY;
begin
 TempDir:= encode_dir(direction);
 Result:=CrdToString(TempDir.X,TempDir.Y); 
end;

function isCorrectDir(direction:integer;DirStr:string):boolean;// проверка правильности направления
// не пытался ли чар уже идти в данную точку
var
  strDir:string;
begin
 strDir:=DirToStr(direction);
 if (Pos(strDir,DirStr)=0) then Result:=true else Result:=false;
end;

// персечение множества координат вокург себя с координатами в строке Pstr
function AroundSelf(Pstr:string):string;
var 
 i:integer;
 rStr:string;
begin
 rStr:='';
 for i:=N to NW do
  if (not isCorrectDir(i,Pstr)) then rStr:=DirToStr(i)+rStr;
 Result:=rStr;
end;

function code_dir(fX,fY:integer):integer; // из координат назначения получаем направление
var
  tx,ty,t,i:Longint;
begin 
   i:=0;   
   tx:=fX - GetX(self);
   ty:=fY - GetY(self);
   t:=Trunc(Abs(tx));
   if tx<>0 then tx:=tx/t;
   t:=Trunc(Abs(ty));
   if ty<>0 then ty:=ty/t;
   for i:=N to SLF do
    if ((tx=Co_ord_X[i]) and(ty=Co_ord_Y[i])) then Result:=i;	
end;

function detour(dir:integer;ClockWise:boolean):integer; // смена направления 
// ClockWise = true - чар поворачивается по часовой стрелке 
// ClockWise = false - чар поворачивается пhjnbd часовой стрелки
begin
 if ClockWise then
   if dir=7 then Result:=0 else Result:=dir+1
  else
   if dir=0 then Result:=7 else Result:=dir-1;
end;

function Move(Direction:integer):boolean;// Делает один шаг в указанном направлении
var
 isNotStop, isMove:boolean;
 mx,my:integer;
begin
 mx:=GetX(self);
 my:=GetY(self);
 repeat
  CheckSave;
  isNotStop:=Raw_Move(Direction,false);
  {ToDo- тут следует вставлять проверку на хайд}
  if (((mx-GetX(self))<>0) or ((my-GetY(self))<>0)) then isMove:=true else isMove:=false;
  if isMove then isNotStop:=false;
 until not isNotStop;
 Result:=isMove;
end;

procedure GotoXY(gX:integer;gY:integer;ClWi:boolean;acc:byte); // основная функция
// acc - точность подхода
// ClWi - используется в detour в качестве ClockWise 
var
  isGo:boolean;
  TempDir:integer;
  ReverseDir:integer;
  DirStrNow,DirStrPre:string;
Begin
  if not IsInit then Init_GoXY;
  if ((Abs(GetX(self)-gX)<=acc) AND (Abs(GetY(self)-gY)<=acc)) then exit;
  TempDir:= code_dir(gX,gY);
  repeat
   CheckSave;
   if isCorrectDir(TempDir,DirStrNow) then isGo:=Move(TempDir) else isGo:=false;	
   if isGo then
     begin
      ReverseDir:= revDir[TempDir];
      TempDir:= code_dir(gX,gY);
      if ReverseDir=TempDir then TempDir:=detour(TempDir,ClWi);
      DirStrPre:=DirStrNow;
      DirStrNow:=AroundSelf(DirStrPre);
    end
    else
	 begin
	  DirStrNow:=DirStrNow+DirToStr(TempDir);
	  TempDir:= detour(TempDir,ClWi);
	 end;  
  until ((Abs(GetX(self)-gX)<=acc) AND (Abs(GetY(self)-gY)<=acc));
end;
Last edited by Beren on 11.09.2008 16:09, edited 3 times in total.
Beren
Novice
Novice
Posts: 108
Joined: 08.09.2008 1:07

Post by Beren »

Image
  • GotoXY(1831,2779,true,0)| A->B Дистанция: 324 преодолена за: 0:04:44
    GotoXY(1570,2587,false,0)|B->A Дистанция: 324 преодолена за: 0:23:04
------
мда, на обратном проходе попался дом, что неприятно затянуло путешествие, но зато я увидел пути оптимизации кода)
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Прилепил.
Beren
Novice
Novice
Posts: 108
Joined: 08.09.2008 1:07

Post by Beren »

Обновил немного скрипт, теперь он действует лучше при обходе заборов, стен.
{move_v0_2.inc 11.09.2008}
GotoXY(1831,2779,true,0)| A->B Дистанция: 324 преодолена за: 0:05:10
GotoXY(1570,2587,false,0)|B->A Дистанция: 324 преодолена за: 0:19:27
Dadenyus
Posts: 4
Joined: 24.10.2008 18:44

Post by Dadenyus »

Как сделать чтобы чар бегал а не ходил? :oops:
Post Reply