Эта тема восстановлена из кеша гугла. Если автор сможет повторить свой пост - я этот удалю.
Ходилка
Stealth Client Forum Forum Index -> Scripts
View previous topic :: View next topic
Author Message
Somebody
Neophyte
Joined: 15 Mar 2007
Posts: 19
Location: Odessa
Posted: Mon May 28, 2007 17:55 Post subject: Ходилка
--------------------------------------------------------------------------------
checkflow.inc
Code:
// checkflow.inc 30.06.2007
// написал Somebody. ICQ: 475728522 e-mail: [email protected]
var
CheckSWSTimer : TDateTime;
procedure InitCheckFlow;
begin
CheckSWSTimer := Now;
end;
procedure CheckSave;
var
t : TDateTime;
begin
if InJournalBetweenTimes('Saving World State in a minute', CheckSWSTimer, Now) = -1 then
begin
if InJournalBetweenTimes('Saving World State', CheckSWSTimer, Now) >= 0 then
begin
t := Now;
UOSay('q');
WaitJournalLine(t, 'q', 30000);
SetGlobal('stealth', 'Saving World State', '0');
end;
end
else SetGlobal('stealth', 'Saving World State', '1');
CheckSWSTimer := Now;
end;
function SWSSoon : boolean;
begin
result := (GetGlobal('stealth', 'Saving World State') = '1');
end;
procedure WaitConnection;
begin
if Connected then exit;
while not Connected do wait(100);
wait(3000);
end;
function CheckFlow : integer;
var
delay : integer;
begin
delay := timer;
CheckSave;
WaitConnection;
result := timer - delay;
end;
move.inc
Code:
// move.inc 30.06.2007
// написал Somebody. ICQ: 475728522 e-mail: [email protected]
// Реализация алгоритма "надёжной трассировки"
// http://pmg.org.ru/ai/stout.htm#robust_trace
const
FMoveArrMax = 100; // ставь здесь больше, если твой чар ходит на дистанции больше 13 тайлов или вокруг чара очень много препятствий. Если препятствий на пути мало, то можно оставить как есть.
var
PrognosisX, PrognosisY, FMoveArrCount : integer;
FMoveArr : array [1..FMoveArrMax] of array [1..2] of smallint;
function SetDirection(x, y : integer) : integer;
var
Dir : integer;
begin
if x < GetX(self) then
begin
if y > GetY(self) then Dir := 5;
if y = GetY(self) then Dir := 6;
if y < GetY(self) then Dir := 7;
end;
if x = GetX(self) then
begin
if y > GetY(self) then Dir := 4;
if y < GetY(self) then Dir := 0;
end;
if x > GetX(self) then
begin
if y > GetY(self) then Dir := 3;
if y = GetY(self) then Dir := 2;
if y < GetY(self) then Dir := 1;
end;
result := Dir;
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;
begin
if GetDirection(self) <> Direction then Raw_Move(Direction, RunFlag);
result := Raw_Move(Direction, RunFlag);
end;
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[1]) and (y = FMoveArr[2]) then
begin
result := true;
exit;
end;
end;
end;
function sqr(_int : integer) : integer;
begin
result := _int * _int;
end;
function CalcDist(x, y : integer) : integer;
begin
result := trunc(sqrt(sqr(GetX(self) - x) + sqr(GetY(self) - y)));
end;
procedure SetWrongMove(x, y : integer);
begin
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) : boolean;
var
Dir, Dist, lastX, lastY, t, i, timeout : integer;
begin
FMoveArrCount := 0;
Dist := CalcDist(x, y);
timeout := Dist * 5000; // 5 секунд времени на шаг
t := timer;
while true do
begin
Dist := CalcDist(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, false) then SetWrongMove(lastX, lastY) // отсюда чар пришёл
else SetWrongMove(PrognosisX, PrognosisY);
end;
end;
procedure _move(x, y, tolerance : integer);
begin
while not Move(x, y, tolerance) do wait(100);
end;
Используется так:
Code:
{$Include 'checkflow.inc'}
{$Include 'move.inc'}
...
begin
InitCheckFlow;
...
move(1234, 1234, 0); // или _move(1234, 1234, 0);
...
move(x, y, tolerance);
tolerance - дистанция, на которую чар подойдёт к (x, y)
Пробуйте.
Кстати, я буду рад любым замечаниям и комментариям.
Last edited by Somebody on Wed May 30, 2007 19:59; edited 5 times in total
Back to top
Kilroy
Neophyte
Joined: 17 Mar 2007
Posts: 15
Posted: Tue May 29, 2007 0:24 Post subject:
--------------------------------------------------------------------------------
Чем она отличается от той ходилки которую вылаживали ранее?
Back to top
Somebody
Neophyte
Joined: 15 Mar 2007
Posts: 19
Location: Odessa
Posted: Tue May 29, 2007 17:15 Post subject:
--------------------------------------------------------------------------------
дай ссылку или копипастни сюда ходилку. Я сравню
Back to top
Edred
Moderator
Joined: 28 Mar 2006
Posts: 656
Location: Saint-Petersburg
Posted: Wed May 30, 2007 1:10 Post subject:
--------------------------------------------------------------------------------
Отлично! Наконец кто-то написал ходилку с обходом препятствий.
Надо бы вынести flag в отдельный параметр. То есть выбор бег/хотьба.
Back to top
DerMeister
Novice
Joined: 19 Nov 2006
Posts: 163
Posted: Wed May 30, 2007 2:29 Post subject:
--------------------------------------------------------------------------------
По какому принципу (алгоритму) она троссирует препятствие?
ПС: В пару слов, а то неохота моск себе нагружать разбором кода...
_________________
ЧК
Back to top
Somebody
Neophyte
Joined: 15 Mar 2007
Posts: 19
Location: Odessa
Posted: Wed May 30, 2007 2:43 Post subject:
--------------------------------------------------------------------------------
Edred,
1) "скорость при ходьбе > скорости при беге" - проверял.
2) при ходьбе он идёт плавнее, чем при беге, тоесть выглядит это лучше.
Вывод: Бессмысленный флаг до тех пор, пока Миралекс не доделает хождение. Как только чар сможет нормально бегать, флаг появится.
DerMeister,
шаг в сторону цели
Если невозможно, пометить координаты как заблокированные.
Если возможно, сделать шаг и пометить предыдущую точку как заблокированную.
XXXXX
X <--C
XXXXX
из такой штуки чар не выйдет. Он упрётся в углубление и move надо будет запустить заново.
PS: Я буду вносить некоторые изменения в код. Хорошо бы, чтобы модератор взялся обновлять пост. Эдред, поддержишь?
UPD (насчёт флага, если сильно нужен):
Code:
function TryToMove(Direction : integer; RunFlag : boolean) : boolean;
// меняем на
function TryToMove(Direction : integer) : boolean;
if TryToMove(Dir, false) then SetWrongMove(lastX, lastY)
// превращаем в
if TryToMove(Dir) then SetWrongMove(lastX, lastY)
// и где-нибудь вверху своего скрипта пишем:
const RunFlag = true; // или false
Back to top
Acronym
Apprentice
Joined: 10 May 2005
Posts: 217
Location: Odessa, NDW
Posted: Wed May 30, 2007 10:44 Post subject:
--------------------------------------------------------------------------------
Code:
procedure SetWrongMove(x, y : integer);
begin
if (x = 2084) and (y = 2078) then
***
2084,2078 - Что это? Заранее установленные непроходимые координаты?
_________________
Current version: Stealth 1.0 RC3
Back to top
Edred
Moderator
Joined: 28 Mar 2006
Posts: 656
Location: Saint-Petersburg
Posted: Wed May 30, 2007 13:24 Post subject:
--------------------------------------------------------------------------------
Введи номер версии скрипта. При каждом обновлении вноси в первый пост правку и изменяй номер версии. Плюс отписаться новым постом о изменениях.
Тему прилепил, чтобы не потерялась.
Back to top
Somebody
Neophyte
Joined: 15 Mar 2007
Posts: 19
Location: Odessa
Posted: Wed May 30, 2007 19:55 Post subject:
--------------------------------------------------------------------------------
вместо номера версии использую дату обновления.
30.06.2007:
- почистил скрипт от ненужного кода (в т.ч. от многих комментариев)
- добавил _move(x, y, tolerance : integer); - чар будет пытаться дойти, пока не дойдёт (либо зациклит скрипт)
В checkflow.inc есть функция SWSSoon:
Code:
CheckFlow;
while SWSSoon wait(1000); // возвращает true, если скоро SWS
Back to top
admir
Neophyte
Joined: 27 Sep 2007
Posts: 24
Posted: Sat Dec 01, 2007 2:34 Post subject:
--------------------------------------------------------------------------------
А спецом сделал дубликаты CHECKSAVE и WAITCONNECTION
чтоб погеморнее было ?
еще такой вопрос - допустим у меня чар идет вниз умирается в угол стола и все застревает на вечно там .
это связано с тем что стелс не меет обрабатываьт пакет с запретом на движение ?
тоесть по сути дела вся ходилка выше написанная не может обойти даже 1 тайл .
Back to top
ruff
Novice
Joined: 26 Sep 2007
Posts: 96
Location: Praha, CZ
Posted: Sat Dec 01, 2007 3:07 Post subject:
--------------------------------------------------------------------------------
admir wrote:
еще такой вопрос - допустим у меня чар идет вниз умирается в угол стола и все застревает на вечно там .
это связано с тем что стелс не меет обрабатываьт пакет с запретом на движение ?
тоесть по сути дела вся ходилка выше написанная не может обойти даже 1 тайл .
[::]|/\/\/\|[:]
%)
Застряет не на вечно, но с этой ходилкой да, т.к. она маркает пройденные клетки как инвалиды (во избежание зацикливания) - на узких коридорах чар оказываеца залочен, вперед инвалид по режекту сервера, назад - промаркано как пройденые. но в случае стола должен бы медленно поползти вдоль его края.
На самом деле есть такая трабла (высокий таймаут у Raw_Move), решаеца.
_________________
--
Looking forward to reading yours.
Back to top
admir
Neophyte
Joined: 27 Sep 2007
Posts: 24
Posted: Sat Dec 01, 2007 3:23 Post subject:
--------------------------------------------------------------------------------
я кстати заметил что при упирании в не проходимый тайл, Рав маут вырабатывает задержку - только зачем ?
как решить
Back to top
Acronym
Apprentice
Joined: 10 May 2005
Posts: 217
Location: Odessa, NDW
Posted: Sat Dec 01, 2007 23:25 Post subject:
--------------------------------------------------------------------------------
admir wrote:
я кстати заметил что при упирании в не проходимый тайл, Рав маут вырабатывает задержку - только зачем ?
как решить
Как решить: попробовать описать маршрут без подобных, непроходимых, тайлов.
_________________
Current version: Stealth 1.0 RC3
Back to top
SaNeK
Neophyte
Joined: 22 Mar 2007
Posts: 48
Location: Kiev
Posted: Wed Jan 16, 2008 21:25 Post subject:
--------------------------------------------------------------------------------
Ходилка хорошая
Предметы обходит всегда через южное направление.
Трабл: если персонаж мертв то некоторое время идет, а потом стопит скрипт. Проглянул не нашел в чем дело. Может подскажите, кто знает?