Function not found + полезности

Anything and all.

Moderators: Murderator+, Murderator

Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Function not found + полезности

Post by Destruction »

В этом топике только полезные скрипты, все обсуждения тут: https://yoko.uokit.com/viewtopic.php?t=9869 !!!

Собственно заели меня вопросы насчёт Function not found - решил собрать все пользовательские функции вместе.

Т.к. искать я не любитель - выкладывать буду свои (вернее еще поищу у Edred'а), не сочтите за лицемерие - шлите свои в ПМ, если они как минимум не хуже - выложу рядом.
Если кого забыл - тоже в ПМ, топик закрытый - обсуждению не подлежит, т.к. кому оно надо - знает (поймёт) как эти функции использовать, а кто не поймёт - тому и не надо.

CheckLag()

Code: Select all

Sub checklag()
deljournal("ackpack")
uo.click("backpack")
repeat
wait(50)
until uo.injournal("ackpack")
endsub
Задача этой функции - пауза. Пауза будет длиться, пока сервер не ответит на последний заданный ему вопрос.
Основные преимущества этой функции над некоторыми аналогами:
1. Функция не удаляет весь журнал Injection.
2. Функция учитывает, что backpack может писаться как с маленькой буквы, так и с большой. С большой встречал, если не ошибаюсь - на Антаресе.
3. Функция не делает лишнего удаления журнала Injection (а следовательно лишней паузы) после ответа от сервера - встречаются и такие индивидумы.

DelJournal()

Code: Select all

Sub deljournal(msg)
while uo.injournal(msg)
uo.setjournalline(uo.injournal(msg)-1,"")
wend
endsub
Задача этой функции - удалить все строки из журнала Injection, где встречается заданный отрывок текста. Преимуществ над аналогами не имеет.

Аналог функции deljournal: DeleteJournal

Code: Select all

Sub DeleteJournal(msg) 
   var nom = UO.InJournal(msg) 
   If nom>0 Then 
      UO.SetJournalLine(Nom - 1," -- replaced -- ")  
      DeleteJournal(msg) 
   EndIf 
endsub
Незнаю, хорошо ли в данном случае использовать рекурсию, судить не мне.

GetWord

Code: Select all

Sub GetWord( st, nom ) 
; (c) Edred 
; Возвращает слово из строки str за номером num 
; если такого слова нет - возвращаем '' 
; 
; Разделителем слов считаем пробел. Несколько пробелов подряд считаются за один. 
; Функция сделана без рекурсии специально для считывания слов из сверхдлинных строк! 
; 
   VAR tmpst, i, dlin, kol = 0, start = 0 
   dlin = len( st ) 
   For i=0 To dlin - 1 
      If mid( st, i, 1 ) == ' ' OR i == dlin - 1 Then 
         kol = kol + 1 
         If kol == nom Then 
            ; это первый пробел после нужного нам слова 
            tmpst = mid( st, start, i - start ) 
            return tmpst 
         Else 
            While mid( st, i, 1 ) == ' ' 
               i = i + 1 
            Wend 
            If kol == nom - 1 Then 
               start = i 
            Endif 
         Endif 
      Endif 
   Next 
   tmpst = '' 
   return tmpst 
endsub
GetDistance

Code: Select all

; Функция GetDistance возвращает расстояние до координат 
; (как UO.GetDistance - до объекта) 
; 
; Почему так - потому что учим математику :) 
; 
Sub GetDistance( X, Y ) 
   VAR A, B, C 
   A = abs( X - UO.GetX() ) 
   B = abs( Y - UO.GetY() ) 
   If A > B Then 
      C = A 
   Else 
      C = B 
   EndIf 
   Return C 
endsub
Abs

Code: Select all

Sub abs(num)
if num < 0 then
return -num
endif
return num
endsub
Сокращения от англиского Absolute - функция возвращает положительное значение переданного числа.

GetResource

Code: Select all

Sub GetResource( typ, kolvo, cont ) 
   ; Берем из указанного контейнера указанное количество ресурса по типу 
   ; Возвращаем 0 если ресурс не найден и 1 если все ок. 
   UO.FindType( typ, '-1', cont )      ; Ищем ресурс в контейнере 
   If UO.FindCount() == 0 Then 
      UO.Print("Resource not found, script terminated") 
      return 0 
   Endif 
   UO.Grab( Str( Kolvo ), 'finditem' ) ; Кладем ресурсы в пак 
   Wait(500) 
   CheckLag() 
   return 1 
endsub
FindSymb()

Code: Select all

Sub FindSymb( symb, st )  
; найти первое вхождение символа в строке. Не найдено - вернем 0 
   VAR dlin = len( st ) - 1 
   VAR i 
   For i = 0 To dlin 
      If st[i] == symb Then 
         return i + 1 
      endif 
   Next 
   i = 0 
   return i 
endsub 
GetQuote

Code: Select all

Sub GetQuote( st, num ) 
; Вырезает и возвращает num-подстроку строки st, ограниченную с обоих 
; сторон кавычками без самих кавычек. Возвращаем пустую строку если ошибка 
   VAR s = 0, i = 0, rt = '' 
   VAR quot = '"' 
   s = FindSymb( quot, st ) 
   If s > 0 Then 
      i = i + 1 
      st = right( st, len(st) - s ) 
      s = FindSymb( quot, st ) 
      If s == 0 Then 
         return '' 
      Endif 
      If i == num   Then 
         ; нашли начало нужной строки 
         st = left( st, s - 1 ) 
         return st 
      Else 
         st = right( st, len(st) - s ) 
         rt = GetQuote( st, num - 1 ) 
         If rt == '' Then 
            return '' 
         Else 
            return rt 
         Endif 
      Endif 
   Endif 
   return '' 
endsub 
WriteSpace()

Code: Select all

Sub WriteSpace( nom ) 
   VAR str1, i 
   str1 = '' 
   If nom < 1 Then 
      return str1 
   endif 
   for i = 1 to nom 
      str1 = str1 + ' ' 
   next 
   return str1 
endsub 
Функция вернёт пробелы, их количество будет равно переданному числу.

GetDir

Code: Select all

; Функция GetDir возвращает направление, по которому надо идти 
; к координате 
; 
Sub GetDir( myx, myy, ox, oy ) 
   VAR I, J 
   J = 0 
   VAR X = ox - myx 
   VAR Y = oy - myy 
   I = GetQDir( Abs(X), Abs(Y) ) 
   If X >= 0 Then 
      If Y >= 0 Then 
         If I == 1 Then 
            J = -2 
         Else 
            If I == 2 Then 
               J = -1 
            Else 
               If I == 3 Then 
                  J = 4 
               EndIf 
            EndIf 
         EndIf 
      Else 
         If I == 1 Then 
            J = 2 
         Else 
            If I == 2 Then 
               J = 3 
            Else 
               If I == 3 Then 
                  J = 4 
               EndIf 
            EndIf 
         EndIf 
      EndIf 
   Else 
      If Y >= 0 Then 
         If I == 1 Then 
            J = -2 
         Else 
            If I == 2 Then 
               J = -3 
            Else 
               If I == 3 Then 
                  J = -4 
               EndIf 
            EndIf 
         EndIf 
      Else 
         If I == 1 Then 
            J = 2 
         Else 
            If I == 2 Then 
               J = 1 
            Else 
               If I == 3 Then 
                  J = -4 
               EndIf 
            EndIf 
         EndIf 
      EndIf 
   EndIf 
   RETURN J 
endsub 
; 
; =============== GETQDIR === 
; 
; 
Sub GetQDir( x, y ) 
   VAR Ep = Val( UO.GetGlobal( 'KoefEp' ) ) 
   VAR J = 0 
   If X == 0 Then 
      J = 1 
   Else 
      If ( Y / X ) < Ep Then 
         J = 3 
      Else 
         If ( X / Y ) < Ep Then 
            J = 1 
         Else 
            J = 2 
         EndIf 
      EndIf 
   EndIf 
   RETURN J 
endsub 
Где-то был аналог от меня, покороче - но он потерялся.

PERP

Code: Select all

; Функция Perp возвращает направление, перпендикулярное введённому 
; 
Sub Perp( Dir ) 
   VAR D = Dir 
   If Dir == 1 Then 
      D = 3 
   EndIf 
   If Dir == 2 Then 
      D = 4 
   EndIf 
   If Dir == 3 Then 
      D = -1 
   EndIf 
   If Dir == 4 Then 
      D = -2 
   EndIf 
   If Dir == -1 Then 
      D = -3 
   EndIf 
   If Dir == -2 Then 
      D = -4 
   EndIf 
   If Dir == -3 Then 
      D = 1 
   EndIf 
   If Dir == -4 Then 
      D = 2 
   EndIf 
   RETURN D 
endsub 
SetArray, RegArray, IncArray, GetArray, ArrCleanValue, DelArr, ArrLen

Code: Select all

Sub ArrCleanValue(val,cl)
; Чистка значения из псевдо-массива
; str 1. "Массив" для чистки
; str 2. Символ(ы) для стирания
var i=0
while MID(val, i, strlen(cl)) == cl
	i = i + strlen(cl)
wend
return MID(val, i, strlen(val)-i)
endsub

Sub RegArray(num,len) 
; Создание псевдо-массива
; val 1. Количество элементов 
; val 2. Длинна элемента (пустота заполняется нуликами, можно еще чем-нить заполнять, мне нулики было удобно). 
var arr="" 
var add="" 
while strlen(add) < len 
add = add + "0" 
wend 
while strlen(arr) < num*len 
arr = arr + add 
wend 
return arr 
endsub

Sub DelArr(arr,len,num)
; удаление значения из псевдо-массива (получается смещение)
; str 1. "Массив"
; int 2. Длинна элемента
; int 3. Номер элемента
var tmp1 = MID(arr,0,len*num)
var tmp2 = MID(arr,len*num+len,strlen(arr)-len*num-len)
return tmp1+tmp2
endsub

Sub ArrLen(arr,len)
; Возвращает количество элементов псевдо-массива
; str 1. "Массив"
; int 2. Длинна значения
return strlen(arr)/len
endsub

Sub SetArray(val,string,num,len)
; Запись в псевдо-массив
; str 1. Записываемое значение 
; str 2. "Массив" 
; val 3. Номер элемента 
; val 4. Длинна элемента "массива" 
if len < strlen(val) then 
uo.print("Value to long!") 
return false 
endif 
while strlen(val) < len 
val = "0"+val 
wend 
return MID(string,0,num*len) + val + MID(string,num*len+len,strlen(string)-num*len-len) 
endsub 

Sub GetArray(str,num,len) 
; Получения значения массива
; str 1. "Массив" 
; val 2. Номер элемента 
; val 3. Длинна элемента "массива" 
; var ret = ArrCleanValue(MID(str,num*len,len),"0")
if NOT strlen(ret) Then
	return "0"
endif
return ret
endsub 

Sub IncArray(str,num,len) 
; Создаст в конце num элементов
; str 1. "Массив" 
; val 2. Количество добавляемых элементов 
; val 3. Длинна элемента "массива". 
; var i,j 
for i=1 to num 
for j=1 to len 
str = str+"0"
next 
next 
return str 
endsub
Набор скриптов для работы с псевдомассивами. Суть в том, что обычно надо создать глобальный массив и хранить там Type'ы или ID'ы, а они как известно имеют фиксированную длинну, собственно функции помогут для обращения с такими массивами.
Может быть полезным, только если понять, зачем я это писал.

FindItem, FindType, FindCount
Улучшенная система поиска вещей.
Смотрим тут: https://yoko.uokit.com/viewtopic.php?p=40604#40604

Math functions
Организация простых математических функций вроде модуля или квадратного корня:
Смотрим тут: https://yoko.uokit.com/viewtopic.php?t=7388&highlight=

Des.Mfgi.*
Усовершенствованная работа с коммандой mfgi.
Смотрим тут: https://yoko.uokit.com/viewtopic.php?p=45275

Идея Destruction'а (function not found), расширение I'm'A (полезности)
Last edited by Destruction on 2006-11-23 12:31:58, edited 4 times in total.
I'm
Expert!
Posts: 1396
Joined: 2004-10-15 22:38:04
Location: Moscow City.
Contact:

Post by I'm »

Время и дата в нормальном формате (inside) by Mihail

Code: Select all

sub main()
uo.print(date(uo.date(),'.'))
uo.print(time(uo.time(),':'))
end sub
где jor - это время\дата в формате числа, а n - нужный вам разделитесь.

Code: Select all

sub date(jor,n)
#Mihail
var ser=str(jor), t=''
if len(ser)==5 then
ser='0'+ser
end if
t=right(ser,2)+n+mid(ser,2,2)+n+left(ser,2)
return t
end sub

Code: Select all

sub time(jor,n)
#Mihail
var i, t=''
var ser=str(jor)
for i=0 to len(ser)-2 step 2
t=t+mid(ser,i,2)+n
next
t=left(t,len(ser)+2)
return t
end sub
The End.
I'm
Expert!
Posts: 1396
Joined: 2004-10-15 22:38:04
Location: Moscow City.
Contact:

Post by I'm »

Делаем скрин и называем его красиво by Кто-то :)

Code: Select all

sub MakeScreen() 
Var FileName 
  FileName=UO.GetInfo("shard")+" ("+UO.GetInfo("character")+") "+UO.asmGetDate("dd/mm/yy")+" "+UO.asmGetTime("h.n.s") +".bmp" 
  UO.Snap("BMP",FileName) 
end sub 
Для работы требуется ASM
The End.
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Есть ребятки у меня ещё одна полезность -)

Code: Select all

Sub Des.String.GetWord(string, num)
var i, prev, words, word=""
if Des.String.GetWordsCount(string) < num then
	return ERROR
endif
if strlen(string) then
	words = 1
else
	words = 0
endif
var flag_ap = false
var flag_qu = false
var p_flag_ap = false
var p_flag_qu = false
for i=0 to strlen(string)-1
	p_flag_ap = flag_ap
	p_flag_qu = flag_qu
	if NOT flag_ap AND NOT flag_qu Then
		if MID(string, i, 1) == " " AND NOT prev == " " OR MID(string, i, 1) == "	" AND NOT prev == "	" then
			words = words + 1
		endif
		if MID(string, i, 1) == "'" AND prev == " " OR prev == "	" then
			flag_ap = true
		endif
		if MID(string, i, 1) == '"' AND prev == " " OR prev == "	" then
			flag_qu = true
		endif
	else
		if flag_ap then
			if MID(string, i, 1) == "'" then
				flag_ap = false
			endif
		endif
		if flag_qu then
			if MID(string, i, 1) == '"' then
				flag_qu = false
			endif
		endif
	endif
	prev = MID(string, i, 1)
	if words == num AND NOT MID(string, i, 1) == "
" then
		if flag_ap == false AND flag_qu == false AND NOT p_flag_ap AND NOT p_flag_qu then
			word = word + MID(string, i, 1)
		endif
		if flag_ap == true AND NOT MID(string, i, 1) == "'" then
			word = word + MID(string, i, 1)
		endif
		if flag_qu == true AND NOT MID(string, i, 1) == '"' then
			word = word + MID(string, i, 1)
		endif
	endif
next
return TRIM(word)
endsub

Code: Select all

Sub Des.String.GetWordsCount(string)
var i, prev = "", words
if strlen(string) then
	words = 1
else
	words = 0
endif
var flag_ap = false
var flag_qu = false
for i=0 to strlen(string)-1
	if NOT flag_ap AND NOT flag_qu Then
		if (MID(string, i, 1) == " " OR MID(string, i, 1) == "	") AND NOT prev == " " AND NOT prev == "	" then
			words = words + 1
		endif
		if MID(string, i, 1) == "'" AND prev == " " OR prev == "	" then
			flag_ap = true
		endif
		if MID(string, i, 1) == '"' AND prev == " " OR prev == "	" then
			flag_qu = true
		endif
	else
		if flag_ap then
			if MID(string, i, 1) == "'" then
				flag_ap = false
			endif
		endif
		if flag_qu then
			if MID(string, i, 1) == '"' then
				flag_qu = false
			endif
		endif
	endif
	prev = MID(string, i, 1)
next
return words
endsub
Первая функция - выдёргивает слово с порядковым номером, который укажем. Вторая - считает количество слов в переданной строке.

Но тут - есть одна особенность - строка заключанная в кавычки или апострофы является одним словом, неправда ли - хорошо? -)

PS: Просто вспомнил, что есть - не тестировал, так, что вы уж как-нибудь сами.
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Code: Select all

; arguments: mixed msg
Sub die( msg )
	if isArray(msg) OR isClass(msg) then
		msg = ""
	endif
	if not isString( msg ) then
		msg = str( msg )
	endif
	uo.print( msg )
	uo.exec("terminate all")
endsub
Коротко и просто -) Функция принимает любые значения в качестве аргумента, жалко сделать необязательный аргмент - нельзя -(

А как вы думали я отлаживаю свои скрипты ? -))
GimFlex
Expert!
Posts: 766
Joined: 2005-01-07 13:22:19
Contact:

Post by GimFlex »

вот значит у нас есть сумочка в ней есть однотипные предметы но в нескольких кучках ( например золото или свитки при пркоачке инскрипта) так вот скриптец считает общее количество предметов во всех стопках очень удобно при подсчете денег и при прокачке инскрипта кстати в сумке могут быть вещи разных типов все подсчитает :)

Code: Select all

Sub podschet()
	var fl=1
	var tip,name="",chis=0
	uo.print('Conteiner dly podscheta?') 
	uo.exec('addobject cont') 
	while uo.targeting() 
		wait(100) 
	wend 
	uo.textclear()
	uo.textopen()
	uo.useobject('cont')
	wait(1000)
	while fl==1
		uo.findtype('-1','-1','cont')
		if uo.findcount() then
			uo.click('finditem')
			while name=="" 
				name=uo.getname('finditem')
				wait(10)
			wend 
			tip=uo.GetGraphic('finditem')
			uo.findtype(tip,'-1','cont')
			while uo.findcount()
				chis=uo.getquantity('finditem')+chis
				uo.ignore('finditem')
				uo.findtype(tip,'-1','cont')
			wend
			uo.textprint(name+"  общее количество:  "+str(chis))
		else
			fl=0  
		endif 
		name=""
		chis=0
	wend
	uo.ignorereset()
endsub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Ещё пачка свеженаписанных полезностей с использованием недавно найденной фичи (описал в разделе FAQ).

Полезности используют друг-друга, так, что с ошбками вроде "Function not found" - не приставать -)

Итак, функция первая -) Проверяет - есть ли в переданном массиве переменная. Если нет - возвращает -1, если есть - порядковый номер элемента массива.

Если вместо массива передать строку, а вместо строки - один символ, то функция вернёт первое вхождение символа в строке.

Регистронезависимый поиск работает значительно медленее, используйте только при острой необходимости!

Code: Select all

; int inArray( string, array, bool, int )
; str - какую строку искать
; arr - массив, в котором искать
; nocase - true, чтобы не учитывался регистр при поиске.
; arr_len - длинна переданного массива
Sub inArray( str, arr, nocase, arr_len )
	var i
	if nocase then
		str = StrToLower( str )
	endif
	for i=0 to arr_len-1
		if nocase then
			if StrToLower( arr[i] ) == str then
				return i
			endif
		else
			if arr[i] == str then
				return i
			endif
		endif
	next
	return -1
endsub
Собственно ещё две функции - StrToUpper и StrToLower, соответсвенно переводят переданную строку в верхний или нижний регистр.
Работают медленно, поэтому в режиме реального времени - не получится. Может пригодится для разовых преобразований.

Функции UpperWords и LowerWords возвращают массивы с русскими и англискими буквами соответствующего регистра. Чтобы всё сработало корректно - в функцию необходимо передать массив размером не менее 59 элементов (смотри функции StrToLower и StrToUpper).

Code: Select all

sub StrToLower( str )
	var num, i, j
	DIM lower[59]
	lower = LowerWords( lower )
	DIM upper[59]
	upper = UpperWords( upper )
	for i=0 to strlen( str )-1
		num = inArray( str[i], upper, 0, 59)
		if num > -1 then
			str = left( str, i ) + lower[ num ] + right( str, strlen( str ) -i -1 )
		endif
	next
	return str
endsub

sub StrToUpper( str )
	var num, i, j
	DIM lower[59]
	lower = LowerWords( lower )
	DIM upper[59]
	upper = UpperWords( upper )
	for i=0 to strlen( str )-1
		num = inArray( str[i], lower, 0, 59)
		if num > -1 then
			str = left( str, i ) + upper[ num ] + right( str, strlen( str ) -i -1 )
		endif
	next
	return str
endsub

Sub LowerWords(words)
	words[0] = "q"
	words[1] = "w"
	words[2] = "e"
	words[3] = "r"
	words[4] = "t"
	words[5] = "y"
	words[6] = "u"
	words[7] = "i"
	words[8] = "o"
	words[9] = "p"
	words[10] = "a"
	words[11] = "s"
	words[12] = "d"
	words[13] = "f"
	words[14] = "g"
	words[15] = "h"
	words[16] = "j"
	words[17] = "k"
	words[18] = "l"
	words[19] = "z"
	words[20] = "x"
	words[21] = "c"
	words[22] = "v"
	words[23] = "b"
	words[24] = "n"
	words[25] = "m"
	words[26] = "й"
	words[27] = "ц"
	words[28] = "у"
	words[29] = "к"
	words[30] = "е"
	words[31] = "н"
	words[32] = "г"
	words[33] = "ш"
	words[34] = "щ"
	words[35] = "з"
	words[36] = "х"
	words[37] = "ъ"
	words[38] = "ф"
	words[39] = "ы"
	words[40] = "в"
	words[41] = "а"
	words[42] = "п"
	words[43] = "р"
	words[44] = "о"
	words[45] = "л"
	words[46] = "д"
	words[47] = "ж"
	words[48] = "э"
	words[49] = "я"
	words[50] = "ч"
	words[51] = "с"
	words[52] = "м"
	words[53] = "и"
	words[54] = "т"
	words[55] = "ь"
	words[56] = "б"
	words[57] = "ю"
	words[58] = "ё"
	return words
endsub

Sub UpperWords(words)
	words[0] = "Q"
	words[1] = "W"
	words[2] = "E"
	words[3] = "R"
	words[4] = "T"
	words[5] = "Y"
	words[6] = "U"
	words[7] = "I"
	words[8] = "O"
	words[9] = "P"
	words[10] = "A"
	words[11] = "S"
	words[12] = "D"
	words[13] = "F"
	words[14] = "G"
	words[15] = "H"
	words[16] = "J"
	words[17] = "K"
	words[18] = "L"
	words[19] = "Z"
	words[20] = "X"
	words[21] = "C"
	words[22] = "V"
	words[23] = "B"
	words[24] = "N"
	words[25] = "M"
	words[26] = "Й"
	words[27] = "Ц"
	words[28] = "У"
	words[29] = "К"
	words[30] = "Е"
	words[31] = "Н"
	words[32] = "Г"
	words[33] = "Ш"
	words[34] = "Щ"
	words[35] = "З"
	words[36] = "Х"
	words[37] = "Ъ"
	words[38] = "Ф"
	words[39] = "Ы"
	words[40] = "В"
	words[41] = "А"
	words[42] = "П"
	words[43] = "Р"
	words[44] = "О"
	words[45] = "Л"
	words[46] = "Д"
	words[47] = "Ж"
	words[48] = "Э"
	words[49] = "Я"
	words[50] = "Ч"
	words[51] = "С"
	words[52] = "М"
	words[53] = "И"
	words[54] = "Т"
	words[55] = "Ь"
	words[56] = "Б"
	words[57] = "Ю"
	words[58] = "Ё"
	return words
endsub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Ещё маленькая тулза в помощь скриптописателю.

Ищет строку entry в строке str и если найдено - вернёт номер первой буквы entry в строке str.

Если не найдено - вернёт -1.

Code: Select all

; int FindEntry( string, string, bool )
; entry - что ищем
; str - где ищем
; nocase - регистро-независимый поиск
Sub FindEntry( entry, str, nocase )
	var i
	if nocase then
		entry = strtolower( entry )
		str = strotolower( str )
	endif
	for i=0 to strlen( str ) -strlen( entry )
		if MID( str, i, strlen( entry ) ) == entry then
			return i
		endif
	next
	return -1
endsub
Добавлено:
Ещё пара плюшек :-)
ucwords - делает заглавной каждую первую букву слова в переданном тексте.
ucfirst - делает заглавной первую букву в переданном тексте.

Code: Select all

Sub ucwords( str )
	var i, prev = ""
	for i = 0 to strlen( str )-1
		if prev == " " || prev == "	" || prev == "" then
			str = left( str, i ) + strtoupper( str[i] ) + right( str, strlen(str) -i -1 )
		endif
		prev = str[i]
	next
	return str
endsub

Sub ucfirst( str )
	return strtoupper( str[0] ) + right( str, strlen(str) -1 )
endsub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

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

Code: Select all

; Получение направление хождения
; v1.1 (c) 2006, Destruction.
; x = координата X точки - uo.getX();
; y = координата Y точки - uo.getY();
; type = 0 - получение кода клавиши, чтобы пойти. 
; type = 1 - получение направления в котором идти (см. uo.getDir). 
; walk = 0 - направление, чтобы подойти
; walk = 1 - обратно направление (чтобы отойти в противоположную сторону)
Sub getWalkDir(x, y, type, walk) 
   DIM keys[8] 
   if type == 0 then 
      if walk == 0 then
         keys[0] = 35; End 
         keys[1] = 40; Down 
         keys[2] = 34; Page Down 
         keys[3] = 39; Right 
         keys[4] = 33; Page Up 
         keys[5] = 38; Up 
         keys[6] = 36; Home 
         keys[7] = 37; Left 
      else
         keys[0] = 33; Page Up
         keys[1] = 38; Up
         keys[2] = 36; Home
         keys[3] = 37; Left
         keys[4] = 35; End
         keys[5] = 40; Down
         keys[6] = 34; Page Down
         keys[7] = 39; Right
      endif
   else
      if walk == 0 then
         keys[0] = 4; End 
         keys[1] = 3; Down 
         keys[2] = 2; Page Down 
         keys[3] = 1; Right 
         keys[4] = 0; Page Up 
         keys[5] = 7; Up 
         keys[6] = 6; Home 
         keys[7] = 5; Left 
      else
         keys[0] = 0; Page Up
         keys[1] = 7; Up
         keys[2] = 6; Home
         keys[3] = 5; Left
         keys[4] = 4; End
         keys[5] = 3; Down
         keys[6] = 2; Page Down
         keys[7] = 1; Right
      endif
   endif 
   if x==0 && y > 0 then 
      return keys[0] 
   endif 
   if x==0 && y < 0 then 
      return keys[4] 
   endif 
   if x > 0 && y == 0 then 
      return keys[2] 
   endif 
   if x < 0 && y == 0 then 
      return keys[6] 
   endif 
   if x > 0 && y > 0 then 
      return keys[1] 
   endif 
   if x > 0 && y < 0 then 
      return keys[3] 
   endif 
   if x < 0 && y > 0 then 
      return keys[7] 
   endif 
   if x < 0 && y < 0 then 
      return keys[5] 
   endif 
endsub
Примечание: Указывать надо относительные координаты.
Last edited by Destruction on 2007-04-26 18:39:18, edited 2 times in total.
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Ну я собственно говоря, с ещё одной плюшкой.

Суть функции - разбить string используя разделитель pattern и вернуть строку с заданным номером, если строка не найдена - вернёт false.

Code: Select all

; explode( string string, string pattern, number num )
Sub explode( string, pattern, num ) 
var i, counter = 0, entry = 0 
for i=0 to strlen( string ) -strlen( pattern ) 
   if mid( string, i, strlen( pattern ) ) == pattern then 
      counter = counter + 1 
      if num == counter-1 then 
         return mid( string, entry, i-entry ) 
      endif 
      entry = i + strlen( pattern )
   endif 
next 
if entry == 0 then 
   return false 
endif 
return mid( string, entry, strlen(string)-entry ) 
endsub
Пример использования:

Code: Select all

var coordinates = "1928 1644"
var x = explode( coordinates, " ", 0 ) ; в переменную будет записано 1928
var y = explode( coordinates, " ", 1 ) ; в переменную будет записано 1644
uo.print( "X: " + x + ", Y: " + y )
; Результатом будет вывод на экран строки:
; X: 1928, Y: 1644
Last edited by Destruction on 2009-03-21 16:56:23, edited 1 time in total.
I'm
Expert!
Posts: 1396
Joined: 2004-10-15 22:38:04
Location: Moscow City.
Contact:

Post by I'm »

Выключалка компа (была давно тут) by Кто-то :)

Code: Select all

sub TurnOff()
Var OffHours   = 2  # Через сколько часов выключить
Var OffMinutes = 22 # + минуты.
Wait(OffHours*60*60*1000+OffMinutes*60*1000) 
uo.exec("launch shutdown -s -t 5 -c Scipt complete.") 
end sub 
The End.
Savage
Expert!
Posts: 1205
Joined: 2004-04-04 11:13:54
Location: Балаково, Саратовская обл.
Contact:

Паузы в скрипте.

Post by Savage »

Часто в процессе работы скрипта необходимо сделать паузу и поиграть руками. Например, убить элема или риппера при добыче леса и металла.

Предлагаю Вашему вниманию свою реализацию подобной паузы.

Конструкция построена на значениях глобальной переменной "PausedScript", которая принимает два значения: "On" и "Off".
Управляет этой переменной небольшой скрипт на который забинден хоткей в инжекте (у меня ентер на цифровой клавиатуре).

Вот этот скрипт:

Code: Select all

sub PausedSwitch()
	If UO.GetGlobal('PausedScript')=='Off' Then
		UO.SetGlobal('PausedScript','On')
	Else
		UO.SetGlobal('PausedScript','Off')
	Endif
end sub
В начале Вашего скрипта добовляем объявление этой переменной и сразу установим значение "пауза выключена"

Code: Select all

sub tvoy_script()
	UO.SetGlobal('PausedScript','Off')
end sub

В коде Вашего скрипта, допустим, сразу за проверкой на то что добыл чар ставим этот кусок кода

Code: Select all


					If UO.GetGlobal('PausedScript')=='On' Then
						UO.Print("+++ Script paused! +++")
						UO.Print("+++ Script paused! +++")
						TempX=UO.GetX()
						TempY=UO.GetY()
						While UO.GetGlobal('PausedScript')=='On'
							wait(500)
						Wend
						UO.Print("+++ Script continued! +++")
						UO.Print("+++ Script continued! +++")
						SuperWalk(TempX,TempY,"")
					Endif
Или такой, но можно и оба добавить один за другим.

Code: Select all

If UO.Life<UO.Str then
						gong(2)
							
						UO.SetGlobal('PausedScript','On')
						UO.Print("!!! Script paused! !!!")
						UO.Print("!!! Script paused! !!!")
						TempX=UO.GetX()
						TempY=UO.GetY()
						While UO.GetGlobal('PausedScript')=='On'
							wait(500)
						Wend
						UO.Print("!!! Script continued! !!!")
						UO.Print("!!! Script continued! !!!")
						SuperWalk(TempX,TempY,"")
					Endif
В первом случае после нажатия хоткея, чар приостонавливает работу и ждет повторного нажатия хоткея. Во втором чар останавливает свою работу в результате потери некоторого количества ХП и ждет нажатия хоткея.

Функция супервалк не прилагается, она возвращает чара на место.
Зато прилагается функция звукового оповещения :)

Code: Select all

#==============================================================
#  Gong(counter) - playing wav-file 'counter'-times
#  http://www.djetta.ru/cow.wav
#--------------------------------------------------------------
sub Gong(times) ; play wav-file
	VAR i
	for i=1 to times
		UO.Exec("playwav d:\game\uo\injection\cow")
		wait(1200) ; time to play sample at once
	next
end sub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Как же удобно добавлять таргеты объектом, чтобы их потом юзать ?

Но как же неприятно писать на это целых 4 строчки? -))

Собственно я решил упростить скриптерам задачу, если никто не против.

Code: Select all

 ; Модифицированная функция добавляения объекта
; Функция ждёт, пока пользователь не добавит объект
; v1.1 (c) 2006, Destruction
Sub my.AddObject( name )
	If uo.Targeting() Then
		uo.Say( chr( 27 ) )
	End If
	If uo.Waiting() Then
		uo.CancelTarget()
	End If
	uo.AddObject( name )
	While uo.Targeting()
		Wait( 100 )
	Wend
End Sub
Last edited by Destruction on 2009-12-07 17:07:17, edited 3 times in total.
Mihail
Expert!
Posts: 548
Joined: 2005-05-20 20:30:10
Contact:

Post by Mihail »

чтобы руками каждый раз названия для массивов не писать:

Code: Select all

sub mass()
#Mihail
var kol = 5; name = 'a' #соотвественно количество и название
var i,j=0
uo.textopen() 
uo.textclear() 
uo.exec('set toptext 1') 
uo.textprint('Сгенерированный массив:') 
uo.textprint() 
uo.textprint('Dim '+name+'['+str(kol)+']') 
for i=0 to kol-1 
uo.textprint(name+'['+str(j)+']='+"'"+"'") 
j=j+1 
next 
uo.textprint()
uo.textprint('Mihail © 2006')
uo.exec('set toptext 0')
end sub
конкретно вот это скрипт выдаст в textbox это:

Code: Select all

Сгенерированный массив:

Dim a[5]
a[0]=''
a[1]=''
a[2]=''
a[3]=''
a[4]=''

Mihail © 2006
[url=http://forum.yoko.com.ua/viewtopic.php?t=7379&start=15#69595][b]"плагины" для инжекта[/b][/url]
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Code: Select all

; Проверка принадлежности числа диапазону
; version 1.0 (c) Destruction
; between( number, number, number, bool )

; num - число которое проверяется на принадлежность диапазону
; min - минимальное число
; max - максимальное число
; strict - строгость проверки
Sub between( num, min, max, strict )
     If num > min && num < max Then
          return true
     End If
     If num >= min && num <= max && Not strict Then
          return true
     End If
     return false
End Sub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Приспичило наваять простенькую ожидалку сообщений с таймаутом.

Зачем таймаут? - При потере пакетов просто необходимая вещь!

Code: Select all

Sub WaitForMsg( msg, timeout )
    deljournal( msg )
    var timer = 0
    repeat
        wait( 100 )
        timer = timer + 1
    until uo.injournal( msg ) || timeout / 100 < timer
End Sub
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Захотелось, подумалось.

Написался поиск на определённых координатах.

После поиска он сразу же снимаем временно повешенный игнор.

Code: Select all

; Поиск объекта на определённых координатах
; (c) 2007, Destruction
Sub LookAtTiles( type, color, object, x1, x2, y1, y2 )
	var tmp, result = "", mDist
	; fix vars
	If x2 > x1 then
		tmp = x1
		x1 = x2
		x2 = tmp
	End If
	If y2 > y1 then
		tmp = y1
		y1 = y2
		y2 = tmp
	End If
	
	; calculate relative coordinates
	var rx1 = x1 - uo.getX()
	var rx2 = x2 - uo.getX()
	var ry1 = y1 - uo.getY()
	var ry2 = y2 - uo.getY()
	
	; absolute relative coordinates
	var arx1 = abs( rx1 )
	var arx2 = abs( rx2 )
	var ary1 = abs( ry1 )
	var ary2 = abs( ry2 )
	
	; calculate max distance
	mDist = arx1
	If mDist < arx2 Then
		mDist = arx2
	End If
	If mDist < ary1 Then
		mDist = ary1
	End If
	if mDist < ary2 Then
		mDist = ary2
	End If
	
	; set finddistance for next searching
	uo.set( 'finddistance', mDist )
	
	; search object
	tmp = ""
	uo.FindType( type, color, object )
	While uo.FindCount()
		If uo.getX( 'finditem' ) <= x1 && uo.getX( 'finditem' ) >= x2 Then
		If uo.getY( 'finditem' ) <= y1 && uo.getY( 'finditem' ) >= y2 Then
			result = result + uo.getSerial( 'finditem' )
		End If
		End If
		tmp = tmp + uo.getSerial( 'finditem' )
		uo.Ignore( "finditem" )
		uo.FindType( type, color, object )
	WEnd
	var i
	For i=0 To StrLen( tmp ) -10 Step 10
		uo.Ignore( MID( tmp, i, 10 ), "off" )
	Next
	return result
End Sub
x1, x2, y1, y2 - соответсвенно координаты углов прямоугольника, в котором ищем.

Пример пользования:

Code: Select all

var res = LookAtTiles( "-1", "-1", "ground", 5576, 5579, 1862, 1859 )
var i
For i=0 To StrLen( res ) -10 Step 10
	uo.print( MID( res, i, 10 ) )
Next
YokoInjection CodeSweeper
Function not found?
Possession of mathematics at the level of art - a gift that is only available for election.
Sorry for my clumsy English.
Telegram: @tatikom
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Некоторое время пробывал работать с реестром - ставить ASM мне крайне не хотелось, а в цифрах (set|get)EasyUO я начал путаться.

Включил мозг - вспомнил школу, вспомнил перевод из A > DEC, написал. Решил поделится:

Code: Select all

; Функция считывания переменных EasyUO. Работает так же как uo.getEasyUO за тем исключением, что аргумент - строка, а не число.
Sub my.getEasyUO( str1 )
	return uo.getEasyUO( Str2Int( str1 ) )
endsub

; Функция назначения переменных EasyUO. Работает так же как uo.setEasyUO за тем исключением, что первый аргумент - строка, а не число.
Sub my.setEasyUO( str1, str2 )
	return uo.setEasyUO( Str2Int( str1 ), str2 )
endsub

; Функция перевода строки в число.
; В случае неизвестного символа выводит предупреждение и возвращает -1.
Sub Str2Int( str )
	var w, i, j, alphabet = "", result = 0
	; непосредственно алфавит, который используется
	; изменение алфавита приведёт к изменению результатов работы функции
	; соответсвенно изменять - крайне не рекоммендую.
	alphabet = alphabet + "0123456789"
	alphabet = alphabet + "qwertyuiopasdfghjklzxcvbnm"
	alphabet = alphabet + "QWERTYUIOPASDFGHJKLZXCVBNM"
	alphabet = alphabet + ",.+-*/:;_"
	var alpha_len = strlen( alphabet )
	for i = 0 to strlen( str ) -1
		w = -1
		for j = 0 to alpha_len -1
			if str[i] == alphabet[j] then
				w = j
				j = alpha_len -1
			endif
		next
		if w == -1 then
			uo.print( "Error: unknown symbol " + str[i] )
			return -1
		endif
		result = result + math.pow( w*alpha_len, i )
	next
	return result
endsub
Пример использования:

Code: Select all

sub main()
	my.setEasyUO( "test", "123" )
	uo.print( my.getEasyUO( "test" ) )
endsub
В скрипте использована функция возведения в степень, которая лежит в соответсвутющем топике:
https://yoko.uokit.com/viewtopic.php?p=63274#63274
YokoInjection CodeSweeper
Function not found?
Possession of mathematics at the level of art - a gift that is only available for election.
Sorry for my clumsy English.
Telegram: @tatikom
Mihail
Expert!
Posts: 548
Joined: 2005-05-20 20:30:10
Contact:

Post by Mihail »

Code: Select all

Sub InfoHP(object) 
#Mihail
var rn, max = uo.getmaxhp(object)/100 
rn = uo.gethp(object)/max 
Return rn 
End Sub
#функция возвращает кол-во хп врага в процентах
Destruction
Junior Expert
Posts: 3221
Joined: 2004-06-24 22:08:56

Post by Destruction »

Писал тут скрипт на БС.. написал пару ф-ций, может кому пригодится..

Некоторые ф-ции взаимосвязаны..

Code: Select all

; поиск строки в подстроке
; Destruction
; highstack - где ищем
; needle - что ищем
Sub strpos( highstack, needle )
	var i
	if strlen( highstack ) < strlen( needle ) then
		return 0
	endif
	for i = 0 to strlen( highstack ) - strlen( needle )
		if MID( highstack, i, strlen( needle ) ) == needle then
			return i + 1
		endif
	next
	return 0
endsub

Code: Select all

; Аналог uo.injournal с доп. параметром
; Destruction
; msg - искомое сообщение (или его часть), нельзя использовать разделитель "|"
; author_id - идентификатор автора сообщения
; limit - количество строк в которых производить поиск
Sub my.injournal( msg, author_id, limit )
	if limit < 0 then
		exit( 30, "Incorrect use of function my.injournal!" )
	endif
	if limit > 99 then
		limit = 99
	endif
	var i
	for i = 0 to limit
		if strpos( uo.journal( i ), msg ) && uo.journalserial( i ) == author_id then
			return i + 1
		endif
	next
	return 0
endsub

Code: Select all

; добор ресурсов
; Destruction
; type - графический тип добираемого предмета
; colr - цвет добираемого предмета
; from - контейнер для добора предмета (например "backpack" или "ground")
; where - куда добирать
; quantity - количество которое нужно
; weight - вес добираемого предмета
; Скрипт предназначен для работы со стекующемися предметами, лишние предметы выкладываются обратно, при попытке взять 1 из большой кучи - берётся два, но один потом выкладывается, итп, читайте функцию :)
Sub setItemQuantity( type, colr, from, where, quantity, weight )
	var to_move, flag = true
	while flag
		to_move = quantity
		uo.findtype( type, colr, where )
		while uo.findcount() > 1
			uo.moveitem( "finditem", "0", from )
			wait( move_pause )
			checklag()
			uo.findtype( type, colr, where )
		wend
		if uo.findcount() then
			if uo.getQuantity( "finditem" ) > quantity then
				to_move = 0
				uo.moveitem( "finditem", str( uo.getQuantity( "finditem" ) - quantity ), from )
				wait( move_pause )
				checklag()
			else
				to_move = quantity - uo.getQuantity( "finditem" )
			endif
		endif
		flag = false
		if to_move > 0 then
			uo.findtype( type, colr, from )
			if not uo.findcount() then
				exit( 30, "No ingots found!" )
			endif
			if uo.getQuantity( "finditem" ) < to_move then
				flag = true
				uo.moveitem( "finditem", "0", where )
				wait( move_pause )
				checklag()
			else
				if to_move == 1 && uo.getQuantity( "finditem" )*weight*2 > max_weight then
					to_move = 2
					flag = true
				endif
				uo.moveitem( "finditem", to_move, where )
				wait( move_pause )
				checklag()
			endif
		endif
	wend
endsub

Code: Select all

; Закрытие клиента Ultima Online
; Destruction
; sec - пауза в секундах перед закрытием
; cause - причина, почему уо будет закрыта
; При вызове ф-ции будет инициирован таймер обратного отсчёта по истечении которого уо будет закрыта, полезно в сложных скриптах, например если что-то необходимое для работы скрипта не найдено, а владелец ушёл, если владелец на месте - он успеет прибить таймер :)
Sub exit( sec, cause )
	var i
	uo.print( cause + " Exit after " + str( sec ) + " seconds." )
	for i = 1 to sec
		wait( 1000 )
		uo.print( "Exit after " + str( sec - i ) + "seconds." )
	next
	uo.closeuo()
endsub
YokoInjection CodeSweeper
Function not found?
Possession of mathematics at the level of art - a gift that is only available for election.
Sorry for my clumsy English.
Telegram: @tatikom
Post Reply