Jump to content

Using non-numeric variables in functions (OBSE)


thefleshvirus

Recommended Posts

Thats odd. You could try the eval instead of sv_compare and see what happens maybe as eval came first in OBSE 1.7 and sv_compare in 1.6?

If eval ($one == $Two )
	Set equality to 1
Else 
	Set equality to 0
Endif

 

Yes, looks like that is the correct way to compare strings. While these:

if ( one == two )

or

if ( $one == $two )

- which are without eval - do not works, the script crushes (goes one time and do not respond more).

 

The more complex way is to get every letter out of the string, one by one, but that requires that you want the string to be known.

 

Lets take the first letter T and then the h and check them

if ( sv_Find "T" One 0 1 == 1 )
	Message "The first letter in One is T"
Else
	Message "The first letter in One is not T"
Endif

if ( sv_Find "h" One 1 1 == 1 )
	Message "The second letter in One is h"
Else
	Message "The second letter in One is not h"
Endif
This way is very tedious for sure but it works.

 

Well, I choosed another method:

string_var two

string_var T
string_var h
string_var a
string_var m
string_var r
string_var i
string_var e
string_var l
string_var iter

let T := "moo"
let h := "moo"
let a := "moo"
let m := "moo"
let r := "moo"
let i := "moo"
let e := "moo"
let l := "moo"

ForEach iter<-two
	if eval ( $T == "moo" )
		let T := iter
	elseif eval ( $h == "moo" )
		let h := iter
	elseif eval ( $a == "moo" )
		let a := iter
	elseif eval ( $m == "moo" )
		let m := iter
	elseif eval ( $r == "moo" )
		let r := iter
	elseif eval ( $i == "moo" )
		let i := iter
	elseif eval ( $e == "moo" )
		let e := iter
	elseif eval ( $l == "moo" )
		let l := iter
	endif
loop
MessageBoxEx "%z %z %z %z %z %z %z %z" T h a m r i e l
- and that is "T h a m r i e l"

However, I can't get the such characters functions like "IsLetter" or "CharToASCII" working...

Edited by Stealth21
Link to comment
Share on other sites

I have never used them but they are also from OBSE 1.6 and then the question pops up in my mind: Why are so many functions from OBSE 1.6 obsolete or replaced with other ways? They should work if used properly.

 

We could use some aid here from KatsAwful so lets see if we can get her here. She has some knowledge about OBSE. :wink:

 

If we peek at CharToASCII it only takes the first letter it looks like, which makes sense so it is best used with one single letter at a time I guess.

 

This could be used as well to check a specific letter in a string with loops and that is the oposite ASCIItoChar and that function came with OBSE 1.7 by the way, if it matters at all. A Loop with sv_find but if eval works, we shouldn't complicate it more but what do you wanna use IsLetter and CharToASCII for?

Edited by Pellape
Link to comment
Share on other sites

Yeah that post from QQuix is right. Strings aren't a normal part of Oblivion, and you can't directly compare string variables to literals nor can you just use string variables as normal variables like ref or int. In particular, strings are the buggier of the two additional variable types (array and string) from my experience and its best to be as explicit as possible with the use of eval and parentheses (which not only changes precedence but can substitute results of functions as if they were literals if used with let and eval). Also, make sure you read how sv_compare works. 0 means the strings are equal

 

You should also be able to subscript string variables (string_var[0] for the first character), but this will still require using eval in comparisons. Could also use ForEach loops on strings

 

If you absolutely need ease of use, you can use the underscore prefix block mode to evaluate expressions as literally as possible, see the OBSE Expressions part in the xOBSE docs (llde updated them a bit from the old v.21 version)

 

The following is two ways to get the characters of strings:

scn StringsTest

string_var string
string_var substring
string_var item
int iter
int size

Begin OnActivate
        ; ForEach loop
	let string := "ForEach"
	PrintC "String is: %z", string
	set iter to 0
	ForEach item <- string
		PrintC "Character %g is: %z", iter, item
		let iter += 1
	Loop

        ; SubScripting
	let string := "SubScript"
	PrintC "String is: %z", string
	let size := sv_length string
	set iter to 0
	While (iter < size)
		let substring := string[iter]
		PrintC "Character %g is: %z", iter, substring
		let iter += 1
	Loop
End
Edited by KatsAwful
Link to comment
Share on other sites

That code looks so nice. It is impossible to figure that out by just looking through the functions list for sure, specially that we can get a single character out of a string with brackets or with <- that I have wondered what it is for really as I seen those pointers in some scripts but never figured out how they work. Thanks for making it so clear KatsAwful. :)

Edited by Pellape
Link to comment
Share on other sites

 

short StringValue
 
Let Stringvalue := eval $One
message "One has the value %.0f", StringValue
 
Let Stringvalue := eval $Two
message "Two has the value  %.0f", StringValue
 

 

That is not working (script is rumbling), eval do not "evaluate" the strings.

 

make sure you read how sv_compare works. 0 means the strings are equal

Yes, I read and know about 0, 1 and -1 result states of that function.

Could also use ForEach loops on strings

scn StringsTest

string_var string

string_var item
int iter
int size

Begin OnActivate
; ForEach loop
let string := "ForEach"
PrintC "String is: %z", string
set iter to 0
ForEach item <- string
PrintC "Character %g is: %z", iter, item
let iter += 1
Loop
End

 

That's the method I familiated.

 

I don't know where I made a mistake... but now it is gone somehow, and I can make some notes.

According to OBSE docs, A single character is represented by an integer with a value from 0 to 127 corresponding to its ASCII code. So, I wrote next:

 

 

;string_var one
;string_var two
short iii
short T
short h
short a
short m
short r
short i
short e
short l
short TT
short hh
short aa
short mm
short rr
short ii
short ee
short ll
string_var iter


;	let one := "Thamriel"
;	let two := ThamrielRef.Getname

	while ( iii < 128 )
		let iter := ( ASCIIToChar iii )
		if eval ( $iter == "T" )
			if ( TT != 0 )
				set T to iii
			else
				set TT to iii
			endif
		elseif eval ( $iter == "h" )
			if ( hh != 0 )
				set h to iii
			else
				set hh to iii
			endif
		elseif eval ( $iter == "a" )
			if ( aa != 0 )
				set a to iii
			else
				set aa to iii
			endif
		elseif eval ( $iter == "m" )
			if ( mm != 0 )
				set m to iii
			else
				set mm to iii
			endif
		elseif eval ( $iter == "r" )
			if ( rr != 0 )
				set r to iii
			else
				set rr to iii
			endif
		elseif eval ( $iter == "i" )
			if ( ii != 0 )
				set i to iii
			else
				set ii to iii
			endif
		elseif eval ( $iter == "e" )
			if ( ee != 0 )
				set e to iii
			else
				set ee to iii
			endif
		elseif eval ( $iter == "l" )
			if ( ll != 0 )
				set l to iii
			else
				set ll to iii
			endif
		endif
		set iii to iii + 1
	loop
		MessageBox "T: %.0f h: %.0f a: %.0f m: %.0f r: %.0f i: %.0f e: %.0f l: %.0f"  TT hh aa mm rr ii ee ll
;step aside gives another messagebox
		MessageBox "T: %.0f h: %.0f a: %.0f m: %.0f r: %.0f i: %.0f e: %.0f l: %.0f" T h a m r i e l

 

Each letter in the word "Thamriel" has a two representations in the ASCII codes:

T: 84 , 116

h: 72 , 104

a: 65 , 97

m: 77 , 109

r: 82 , 114

i: 73 , 105

e: 69 , 101

l: 76 , 108

But as I imperically obtained, the values in the first column are for the upprecases and in the second column are for the lowercases.

 

what do you wanna use IsLetter and CharToASCII for?

I am just was wondering WHAT is the reason sv_Compare's result is not zero while both "one" and "two" strings are equal. I thought that the reason is that the ASCII codes of the letters from the one string will be different from the ASCII codes of the letters from another string. But those codes are same. Edited by Stealth21
Link to comment
Share on other sites

You don't need to evaluate anything with let statements, let already does that its why it was created. eval is for vanilla expressions/statements (set and if). What might be happening is a minor compiler error where its f*#@ing up with precedence if it fails without eval. Try enclosing the stringized string, that essentially evaluates the stringize before it gets assigned to your variable

 

I'm confused as to your exact problem with characters, could you write a script showcasing what your mean?

Link to comment
Share on other sites

You don't need to evaluate anything with let statements

I knew that, but just in case I just checked the code which Pellape wrote, and noted to him that it is not working.

 

I found out 'the mystery' of sv_Compare... I was comparing the strings this way:

sv_Compare (one two)

but it have to be in this way:

sv_Compare ($one two)

or

sv_Compare ( "String_to_compare_with" two )

(and in this way script can not be compiled: sv_Compare ($one $two) )

And that's all. I even do not make any mod, I just was wondering))

 

The presence of the symbol "$" was not obvious for me, especially from such explanation like:

(comparison:int) sv_Compare formatString:string var1 var2 ... var20 variable:string_var caseSensitive:bool

Edited by Stealth21
Link to comment
Share on other sites

Well I took a wild guess there anyway, to see if it could return a value really. ;)

 

ASCII-Codes are case dependent. T is not the same as t and H and h do have different Ascii-Codes.

 

A = 65

a = 97

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...