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

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

тут можно задать вопрос по скриптингу
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post 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.
Last edited by lemonter on 11.06.2012 22:23, edited 1 time in total.
nepopus
Novice
Novice
Posts: 121
Joined: 29.02.2012 23:45
Location: Москва
Contact:

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

Post by nepopus »

Лично мне противно разбираться в такой каше.
<( o_O<) <( O_O )> (>O_o )>
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post by lemonter »

Все просто сначала описано 3 функции каждая на свой предмет(под тинкер,карп и тайлор)тобишь куда сувать готовое изделие.
Потом 3 функции самого кача крафтовых скилов.
И в конце уже сам вызов этих функций.
nepopus
Novice
Novice
Posts: 121
Joined: 29.02.2012 23:45
Location: Москва
Contact:

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

Post by nepopus »

lemonter wrote:Все просто сначала описано 3 функции каждая на свой предмет(под тинкер,карп и тайлор)тобишь куда сувать готовое изделие.
Потом 3 функции самого кача крафтовых скилов.
И в конце уже сам вызов этих функций.
Все просто, но у тебя где-то ошибка, и ты попросил нас ее найти. Сделай хотя бы отступы.
<( o_O<) <( O_O )> (>O_o )>
alpi
Novice
Novice
Posts: 51
Joined: 02.07.2009 17:37
Contact:

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

Post 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:
just student
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post by lemonter »

На шарде где я играю навык развивается до 120.0, максимальный рост в сутки 0.5 ,поэтому не вижу смысла ставить 100.0
alpi
Novice
Novice
Posts: 51
Joined: 02.07.2009 17:37
Contact:

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

Post 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('проверка недостаточно пройдена');
и т.д, потом уберешь - возможно, не отлавливается через журнал какая-то фраза, и ее нужно по-другому записать.
just student
nepopus
Novice
Novice
Posts: 121
Joined: 29.02.2012 23:45
Location: Москва
Contact:

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

Post by nepopus »

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

Code: Select all

Getskillvalue('Tinkering') >= 103.8
как предложил alpi.
<( o_O<) <( O_O )> (>O_o )>
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post 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 по гампу на каждый предмет ставится клеймо мастера,да на него нужно отвечать при крафте каждого предмета)так идет пока в журнале не появятся слова вы закончили и тд.пофакту он должен сказать коли скила столько же указанную текстовку но скрипт молчит,идет дальше проверяет иии начинает весь скрипт по началу,проверка по последнему антил не проходит.причина по которой он не правильно распознает цифру мне не понятна.
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post 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
Как вывести значение навыка в журнал не знаю(.
Помогите пожалуйста кто ни-будь.
nepopus
Novice
Novice
Posts: 121
Joined: 29.02.2012 23:45
Location: Москва
Contact:

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

Post by nepopus »

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

Code: Select all

addtosystemjournal(floattostrf(getskillvalue('Tinkering'), ffgeneral, 4, 2));
Попробуй сначала написать скрипт для одного скила, взяв за пример один из предложенных на этом форуме.
<( o_O<) <( O_O )> (>O_o )>
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post 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;
Пашет))Хотя это конечно и не идеальный вариант(
NoSilence
Novice
Novice
Posts: 94
Joined: 02.01.2010 13:55

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

Post 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]: Достигнут лимит навыка.
///
User avatar
Vizit0r
Developer
Developer
Posts: 3958
Joined: 24.03.2005 17:05
Contact:

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

Post 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 секунды от времени ошибки.
тогда уже будет видно, что где.
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
lemonter
Neophyte
Neophyte
Posts: 37
Joined: 14.05.2011 7:59

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

Post 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
Post Reply