Page 1 of 2

Выход из цикла

Posted: 10.06.2012 20:14
by lemonter
Выход из цикла не срабатывает помогите пожалуйста.
Да может я гдето накосячил в программе но в целом когда скилл доходит до нужного значения он упорно продолжает сливать ресы и не переходит к качу другого навыка.

Code: Select all

Program New;
var
rubanoktime:TDateTime;

procedure tailor_drop();
begin
 if (findtype($0E34,backpack)<>0) then
   repeat
     moveitem(findtype($0E34,backpack),0,$5AD46CF1,0,0,0);
     wait(1500);
   until(findtype($0E34,backpack)=0);
end;

procedure izdelie_drop_tinker();
begin
   if(findtype($0FA6,backpack)<>0)then       //шахматы
      repeat
        moveitem(finditem,0,ground,2,0,0);
        wait(1500);
      until(findtype($0FA6,backpack)=0);
end;

procedure izdelie_drop_carp();
begin
  if(findtype($27AE,backpack)<>0)then       //нунчаки
    repeat
       moveitem(finditem,0,ground,2,0,0);
       wait(1000);
    until(findtype($27AE,backpack)=0);
end;

procedure tinker();
begin
 repeat
  rubanoktime:=now;
  useobject(findtype($1EB9,backpack));
  wait(2000);
  if((InJournalBetweenTimes('System: Этот предмет поломан, отнесите его мастеру',rubanoktime,Now)<>-1))then
    begin
    drophere(finditem);
    wait(3000);
    ClearJournal;
    if((count($1EB9)<1))then
     exit;
    useobject(findtype($1EB9,backpack));
    wait(1000);
    end;
 waitgump('4006');
 waitfortarget(5000);
 targettoobject(findtypeex($1BDD,$0000 ,ground,false));  
 wait(1000);
   repeat
    waitgump('100');
    wait(500);
    izdelie_drop_tinker();
    wait(1000);
    if(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)then
     uosay('Дерево кончилось!!!');
   until((InJournalBetweenTimes('Вы закончили',rubanoktime,Now)<>-1)or
   (InJournalBetweenTimes('поломан',rubanoktime,Now)<>-1)or
   (InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)or
   (InJournalBetweenTimes('Какой',rubanoktime,Now)<>-1));
   ClearJournal;
 until(dead or(Getskillvalue('Tinkering')=103.8));
end;

procedure carpentry();
begin
repeat
rubanoktime:=now;
useobject(findtype($1032,backpack));
wait(2000);
if ((InJournalBetweenTimes('System: Этот предмет поломан, отнесите его мастеру',rubanoktime,Now)<>-1))then
 begin
 drophere(finditem);
 wait(3000);
 ClearJournal;
  if((count($1032)<1))then
  exit;
 useobject(findtype($1032,backpack));
 end;
waitgump('10158');
waitfortarget(5000);
targettoobject(findtypeex($1BDD,$01BF,ground,false));  
wait(1000);
repeat
waitgump('100');
wait(500);
izdelie_drop_carp();
wait(1000);
if(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)then
uosay('Дерево кончилось!!!');
until((InJournalBetweenTimes('Вы закончили',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('поломан',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('Какой',rubanoktime,Now)<>-1));
until(dead or (Getskillvalue('Carpentry')=103.5));
end;

procedure tailor();
begin
repeat
rubanoktime:=now;
useobject(findtype($0F9D,backpack));
wait(1000);
 if ((InJournalBetweenTimes('System: Этот предмет поломан, отнесите его мастеру',rubanoktime,Now)<>-1))then
 begin
 drophere(finditem);
 wait(3000);
 ClearJournal;
  if((count($0F9D)<1))then
  exit;
 useobject(findtype($0F9D,backpack));
 end;
waitgump('3636');
waitfortarget(5000);
if (findtype($1766,$5AD46CF1)<>0) then
targettoobject(findtype($1766,$5AD46CF1));
if (findtype($1766,$5AD46CF1)=0) then
uosay('Ткань кончилась положите еще срочно!!!');
wait(1000);
repeat
waitgump('100');
wait(500);
tailor_drop();
if(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)then
uosay('Ткань кончилась положите еще срочно!!!');
until((InJournalBetweenTimes('Вы закончили',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('поломан',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('Какой',rubanoktime,Now)<>-1));
wait(1000);
until(dead or(Getskillvalue('Tailoring')=112.1));
end;

begin
tailor();
carpentry();
tinker();
end.

Re: Выход из цикла

Posted: 10.06.2012 23:30
by nepopus
Лично мне противно разбираться в такой каше.

Re: Выход из цикла

Posted: 11.06.2012 7:41
by lemonter
Все просто сначала описано 3 функции каждая на свой предмет(под тинкер,карп и тайлор)тобишь куда сувать готовое изделие.
Потом 3 функции самого кача крафтовых скилов.
И в конце уже сам вызов этих функций.

Re: Выход из цикла

Posted: 11.06.2012 12:41
by nepopus
lemonter wrote:Все просто сначала описано 3 функции каждая на свой предмет(под тинкер,карп и тайлор)тобишь куда сувать готовое изделие.
Потом 3 функции самого кача крафтовых скилов.
И в конце уже сам вызов этих функций.
Все просто, но у тебя где-то ошибка, и ты попросил нас ее найти. Сделай хотя бы отступы.

Re: Выход из цикла

Posted: 11.06.2012 16:38
by alpi
until(dead or(Getskillvalue('Tinkering')=103.8);

значения скила поменяй на 100.0 во всех случаях, считается реальный скилл.

и делай отступы. посмотри как другие скрипты оформлены.
когда скрипт оформлен правильно, его можно быстро пробежать глазами, определить логику, найти ошибку.
разбираться в твоем хаосе никто не будет.
логика простая - когда просишь помощи - уважай чужое время.

Code: Select all

procedure tailor_drop();
  begin
    if (findtype($0E34,backpack)<>0) then
      repeat
        moveitem(findtype($0E34,backpack),0,$5AD46CF1,0,0,0);
        wait(1500);
      until(findtype($0E34,backpack)=0);
  end;
времени такое оформление занимает самую малость, а пользы от него - цельный вагон .. :wink:

Re: Выход из цикла

Posted: 11.06.2012 22:16
by lemonter
На шарде где я играю навык развивается до 120.0, максимальный рост в сутки 0.5 ,поэтому не вижу смысла ставить 100.0

Re: Выход из цикла

Posted: 11.06.2012 22:52
by alpi
попробуй так:

until dead or (Getskillvalue('Tinkering') >= 103.8) ;

у тебя он не выходит либо здесь, либо ниже

Code: Select all

until((InJournalBetweenTimes('Вы закончили',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('поломан',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)or
(InJournalBetweenTimes('Какой',rubanoktime,Now)<>-1));
вот такую конструкцию можно сократить к такому виду

Code: Select all

until InJournalBetweenTimes('Вы закончили|поломан|недостаточно|Какой',rubanoktime,Now) <> -1;
если проблема в этом выходе - для отладки можешь перед окончанием цикла добавить что-то вроде:

Code: Select all

if InJournalBetweenTimes('поломан',rubanoktime,Now)<>-1 then AddToSystemJournal('проверка поломан пройдена');
if InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1 then AddToSystemJournal('проверка недостаточно пройдена');
и т.д, потом уберешь - возможно, не отлавливается через журнал какая-то фраза, и ее нужно по-другому записать.

Re: Выход из цикла

Posted: 12.06.2012 17:09
by nepopus
Думаю дело не в циклах, т.к. он не замирает, а продолжает делать.
Попробуй выводить значение скила в журнал в конце основного цикла и поставь

Code: Select all

Getskillvalue('Tinkering') >= 103.8
как предложил alpi.

Re: Выход из цикла

Posted: 13.06.2012 8:40
by lemonter

Code: Select all

procedure tinker();
begin
 repeat
  rubanoktime:=now;
  useobject(findtype($1EB9,backpack));
  wait(2000);
   if((InJournalBetweenTimes('System: Этот предмет поломан, отнесите его мастеру',rubanoktime,Now)<>-1))then
    begin
    drophere(finditem);
    wait(3000);
    ClearJournal;
     if((count($1EB9)<1))then
      exit;
    useobject(findtype($1EB9,backpack));
    wait(1000);
    end;
  waitgump('4006');
  waitfortarget(5000);
  targettoobject(findtypeex($1BDD,$0000 ,ground,false));  
  wait(1000);
  repeat
   waitgump('100');
   wait(500);
   izdelie_drop_tinker();
   wait(1000);
   if(InJournalBetweenTimes('недостаточно',rubanoktime,Now)<>-1)then
   uosay('Дерево кончилось!!!');
  until InJournalBetweenTimes('Вы закончили|поломан|недостаточно|Какой',rubanoktime,Now) <> -1;
   if Getskillvalue('Tinkering')>=104.6 then
    uosay('Скила хватает что за бред??');
 until(dead or (Getskillvalue('Tinkering')>=104.6));
end;
Обьясняю что должно быть и что есть.
Используется тинкер тул на дерево,по гампу отвечает что делать,после чего делается 10 шт при крафте каждой (когда навыка больше 100 по гампу на каждый предмет ставится клеймо мастера,да на него нужно отвечать при крафте каждого предмета)так идет пока в журнале не появятся слова вы закончили и тд.пофакту он должен сказать коли скила столько же указанную текстовку но скрипт молчит,идет дальше проверяет иии начинает весь скрипт по началу,проверка по последнему антил не проходит.причина по которой он не правильно распознает цифру мне не понятна.

Re: Выход из цикла

Posted: 13.06.2012 8:51
by lemonter
Тепиерь ловлю вот такую ошибку при выполнении скрипта

Code: Select all

Exception: Access violation at address 0040735C in module 'Stealth.exe'. Read of address 002E2E2A at 10.1249
Начало происходить при замене этого

Code: Select all

if Getskillvalue('Tinkering')>=104.6 then
на это

Code: Select all

if Getskillvalue('Tinkering') >= 103.8 then
Взятие всего условия в скобки не решило проблему.
Переписал циферки и убрал пробел не помогло,заменил цифры на предыдущие,все вернулось на круги своя,где логика???
Добавка переменной типа double и приравнивание ей результата 104.6 а потом замена этого параметра переменной,привела к очередному крашу

Code: Select all

Exception: Access violation at address 0040735C in module 'Stealth.exe'. Read of address 00242E2A at 10.1265
При всем при этом другой скрипт имеет вот такую комбинацию и НИКАКИХ проблем не возникает

Code: Select all

until (dead or(Getskillvalue('Inscription')>=94.0));
Может быть такое то функция Getskillvalue не корректно работает с цифрами выше 100.0?
При изменении

Code: Select all

if Getskillvalue('Tinkering')>=104.6 then
На

Code: Select all

if Getskillvalue('Tinkering')<104.7 then
Вылетает вот такая вот ошибка

Code: Select all

Exception: Range check error at 10.1249
Как вывести значение навыка в журнал не знаю(.
Помогите пожалуйста кто ни-будь.

Re: Выход из цикла

Posted: 13.06.2012 12:51
by nepopus
lemonter wrote:Как вывести значение навыка в журнал не знаю(.
Помогите пожалуйста кто ни-будь.

Code: Select all

addtosystemjournal(floattostrf(getskillvalue('Tinkering'), ffgeneral, 4, 2));
Попробуй сначала написать скрипт для одного скила, взяв за пример один из предложенных на этом форуме.

Re: Выход из цикла

Posted: 13.06.2012 17:12
by lemonter
nepopus wrote:
lemonter wrote:Как вывести значение навыка в журнал не знаю(.
Помогите пожалуйста кто ни-будь.

Code: Select all

addtosystemjournal(floattostrf(getskillvalue('Tinkering'), ffgeneral, 4, 2));
Попробуй сначала написать скрипт для одного скила, взяв за пример один из предложенных на этом форуме.
Скрипт работает хорошо и без всяких проблем кроме той что он не останавливается когда мне это нужно.
Он выводит в журнал

Code: Select all

System: 105
при значении навыка 105.0.
Может он дробные числа как то не правильно обрабатывает,хотя тип double у него =\
Проблема решена комбинацией

Code: Select all

uosay(floattostrf(getskillvalue('Tinkering'), ffgeneral, 4, 2));
wait(300);
until InJournalBetweenTimes('105,1',rubanoktime,Now)<>-1;
Пашет))Хотя это конечно и не идеальный вариант(

Re: Выход из цикла

Posted: 14.06.2012 10:43
by NoSilence

Code: Select all

unit CraftHelper;

interface

procedure InitCraftHelper(SkillName: string; Limit: double);
function CheckSkillValue:boolean;
function CheckSkillLimit:boolean;

implementation

var
	CHSuccCount: integer;
	CHFailCount: integer;
	CHSkillName: string;
	CHLastValue: double;
	CHLimit: double;
	CHLimitReached: boolean;

procedure InitCraftHelper(SkillName: string; Limit: double);
begin
CHSkillName:= SkillName;
CHLastValue:= GetSkillValue(CHSkillName);
CHLimit:= Limit;
CHLimitReached:= false;
CHSuccCount:= 0;
CHFailCount:= 0;
SetEventProc(evIncomingGump, 'CHOnGumpIncoming');
SetEventProc(evUnicodeSpeech, 'CHOnMessage');
end;

function CheckSkillValue:boolean;
begin
if CHLastValue <> GetSkillValue(CHSkillName) then begin
	result:= true;
	CHLastValue:= GetSkillValue(CHSkillName);
	AddToSystemJournal('[' + CHSkillName + ' - ' +
		FloatToStrF(CHLastValue, ffFixed, 4, 1) + ']: ' +
		IntToStr(CHSuccCount + CHFailCount) +
		' (' + IntToStr(Trunc(CHSuccCount*100/(CHSuccCount + CHFailCount))) + '%)');
	CHSuccCount:= 0;
	CHFailCount:= 0;
end;
end;

function CheckSkillLimit:boolean;
begin
if CHLimit > 0 then
	if CHLimitReached or (CHLastValue >= CHLimit) then begin
		result:= true;
		AddToSystemJournal('[' + CHSkillName + ' - ' +
			FloatToStrF(CHLastValue, ffFixed, 4, 1) + ']: ' +
			'Достигнут лимит навыка.');
	end;
end;

procedure CHOnGumpIncoming(ID, GumpID, X, Y: cardinal);
begin
WaitGump('100');
end;

procedure CHOnMessage(Text, SenderName: string; SenderID: cardinal);
begin
if SenderID <> $01010101 then exit;
if BMSearch(0, Text, 'Вы создали') > 0 then
	CHSuccCount:= CHSuccCount + 1
else if BMSearch(0, Text, 'Вы уничтожили') > 0 then
	CHFailCount:= CHFailCount + 1
else if CHLimit >= 999 then
	if (BMSearch(0, Text, 'лимит') > 0) or (BMSearch(0, Text, 'порог') > 0) then				CHLimitReached:= true;
end;

end.
Укомплектовал в отдельный модуль.

Code: Select all

InitCraftHelper('Tinkering', 99.5);
...
  if CheckSkillLimit then exit;
  // 1 цикл крафта
  CheckSkillValue;
...
И сразу же проверил.

Code: Select all

00:27:31:697 [NoSilence]: [Blacksmithy - 105,6]: 351 (89%)
01:49:27:822 [NoSilence]: [Blacksmithy - 105,7]: 598 (90%)
03:12:34:260 [NoSilence]: [Blacksmithy - 105,8]: 601 (89%)
04:33:33:791 [NoSilence]: [Blacksmithy - 105,9]: 583 (91%)
05:56:03:056 [NoSilence]: [Blacksmithy - 106,0]: 598 (88%)
05:57:07:791 [NoSilence]: [Blacksmithy - 106,0]: Достигнут лимит навыка.

Re: Выход из цикла

Posted: 14.06.2012 17:32
by Vizit0r
lemonter wrote:Тепиерь ловлю вот такую ошибку при выполнении скрипта

Code: Select all

Exception: Access violation at address 0040735C in module 'Stealth.exe'. Read of address 002E2E2A at 10.1249
...

Code: Select all

Exception: Access violation at address 0040735C in module 'Stealth.exe'. Read of address 00242E2A at 10.1265

Code: Select all

Exception: Range check error at 10.1249
1) в разделе FAQ тема про отлов ошибок, про последнюю там написано.
2) про первые. ошибка вылетела - сразу идешь в файл Stealth.exe_errors.log в конец файла, и там находишь эту ошибку. От нее и до конца файла - кидаешь сюда. Если не сразу - то всё кидать не надо, а только то, что в 1-2 секунды от времени ошибки.
тогда уже будет видно, что где.

Re: Выход из цикла

Posted: 15.06.2012 7:34
by lemonter

Code: Select all

An exception raised at <<13 Июнь>>, 09:53:14:832
Access violation at address 0040735C in module 'Stealth.exe'. Read of address 0023FFFC
(0000635C){Stealth.exe } [0040735C] System.@DynArrayLength (Line 16784, "sys\system.pas" + 2) + $0

Call stack:
  (0000635C){Stealth.exe } [0040735C] System.@DynArrayLength (Line 16784, "sys\system.pas" + 2) + $0
  (00328DEF){Stealth.exe } [00729DEF] uData.TData.GetKeyWords (Line 477, "uData.pas" + 1) + $9
  (002CDDD2){Stealth.exe } [006CEDD2] ClassCharacter.TCharacter.SendUnicodeText (Line 10801, "ClassCharacter.pas" + 52) + $19
  (002FEE5B){Stealth.exe } [006FFE5B] Script.TScriptThread.SinSendTextToUO (Line 1931, "Script.pas" + 7) + $1B
  (0002CD75){Stealth.exe } [0042DD75] Classes.CheckSynchronize (Line 9835, "common\Classes.pas" + 22) + $8
  (00083696){Stealth.exe } [00484696] Forms.TApplication.WndProc (Line 7831, "Forms.pas" + 144) + $2
  (0002E62C){Stealth.exe } [0042F62C] Classes.StdWndProc (Line 11583, "common\Classes.pas" + 8) + $0

An exception raised at <<13 Июнь>>, 09:53:14:966
Access violation at address 0040735C in module 'Stealth.exe'. Read of address 0023FFFC
(0002D387){Stealth.exe } [0042E387] Classes.TThread.Synchronize (Line 10189, "common\Classes.pas" + 55) + $0

Call stack:
  (0002D382){Stealth.exe } [0042E382] Classes.TThread.Synchronize (Line 10187, "common\Classes.pas" + 53) + $6
  (0002D3AA){Stealth.exe } [0042E3AA] Classes.TThread.Synchronize (Line 10196, "common\Classes.pas" + 4) + $7
  (002FEBEE){Stealth.exe } [006FFBEE] Script.TScriptThread.SendTextToUO (Line 1907, "Script.pas" + 9) + $C
  (00123B7A){Stealth.exe } [00524B7A] uPSRuntime.RealCall_Register (Line 115, "x86.inc" + 16) + $0
  (00124F39){Stealth.exe } [00525F39] uPSRuntime.TPSExec.InnerfuseCall (Line 612, "x86.inc" + 107) + $7E
  (0012A315){Stealth.exe } [0052B315] uPSRuntime.DelphiFunctionProc (Line 11819, "uPSRuntime.pas" + 21) + $1B
  (0012A3BA){Stealth.exe } [0052B3BA] uPSRuntime.DelphiFunctionProc_Register (Line 11832, "uPSRuntime.pas" + 1) + $F
  (0011EA9C){Stealth.exe } [0051FA9C] uPSRuntime.TPSExec.RunScript (Line 7842, "uPSRuntime.pas" + 283) + $16
  (00154B7B){Stealth.exe } [00555B7B] uPSComponent.TPSScript.Execute (Line 678, "uPSComponent.pas" + 8) + $6
  (00313AC0){Stealth.exe } [00714AC0] Script.TScriptThread.ExecuteScript (Line 8252, "Script.pas" + 67) + $B
  (002FD39D){Stealth.exe } [006FE39D] Script.TScriptThread.Execute (Line 1456, "Script.pas" + 97) + $3
  (0002CE84){Stealth.exe } [0042DE84] Classes.ThreadProc (Line 9877, "common\Classes.pas" + 7) + $5
  (0000495C){Stealth.exe } [0040595C] System.ThreadWrapper (Line 12110, "sys\system.pas" + 33) + $0