Finding Rune Count from a Runebook in Orion

Discussion about the technical aspects of scripting. Ask about all issues involving your freelance projects here.
Post Reply
MagicUser
Elder Scribe
Posts: 174
Joined: Mon Nov 03, 2014 2:24 pm
Location: PST

Finding Rune Count from a Runebook in Orion

Post by MagicUser »

I was looking through the gump functions in Orion and an idea popped into my head for finding rune counts based on the runebook (rather than assuming a certain count or having the user define a rune count per book).

There was a problem that did arise while I was working on my idea. Duplicate values for the current charges and the total charges don't show up in the gump texts. Meaning if the user has a book with 12 charges and 12 charges remaining there is only 1 value that shows up in the list. Whereas with 12 charges and 10 charges remaining 2 values show up in the list. These values have to be removed, so I came up with 2 solutions.
  1. Have the user use one of the 12 charges
  2. Remove the 2 first numerics from the front.
The first is the one I went with in the implementation below. People who are looking at runebook usage won't be able to rely on charges anyway.
The second would fail if the user named their runes numerically. Consider 12 charges, 12 chareges left with the first rune being named 0. The list would look like [12, 0, ...]. Meaning the first rune would be removed and not taken into account.

Code: Select all

//book - The serial of the runebook that you want the runecount of.
function getRuneCount(book) {
	var runeCnt = 0;

	var lastGump = Orion.GetGump(any, '0x554B87F3');
	if (lastGump)
		lastGump.Close();
	
	Orion.Wait(1000);
	Orion.UseObject(book);
	if (Orion.WaitForGump(1000)) {
		var gump = Orion.GetGump(any, '0x554B87F3');
		
		if ((gump !== null) && (gump.ID() === '0x554B87F3'))			
			runeCnt = removeBefore(removeAfter(gump.TextList(), 'Empty')).length;
		
		if (runeCnt > 16)
			runeCnt = 16;
		
		lastGump = Orion.GetGump(any, '0x554B87F3');
		if (lastGump)
			lastGump.Close();
	}
	
	return runeCnt;
}

function removeAfter(list, key) {
	var keyFound = false;
	var indexOfKey = 0;
	
	while (indexOfKey < list.length && !keyFound) {
		if (list[indexOfKey] == key)
			keyFound = true;
		else
			indexOfKey++;
	}
	
	var newList = [];
	for (var i = 0; i < indexOfKey; i++) {
		newList[i] = list[i];
	}
	
	return newList;
}

function removeBefore(list) {
	var newList = [];
	
	for (var i = 2; i < list.length; i++) {
		newList[i-2] = list[i];	
	}
	
	return newList
}
I am currently using it with my farming script and works like a charm. Do remember that when using it does need to open the book, so delay should be added to ensure that the book was opened. I use 1000 ms to give adequate time.

I will update this if I find a way around the problem above. Feel free to comment or ask questions.

Update: someone found that there is an edge case if the book is full. I have fixed that by saying if the book has more than 16 elements in the text list (it must be full) then its got 16 runes. Double checked. Still works as intended for books of smaller size. I also added in the delay I talked about, as it could be easy to miss my statement about giving 1000 ms for adequate time.

Thanks Edwin!
Last edited by MagicUser on Sun Sep 26, 2021 12:00 pm, edited 1 time in total.
Respectfully,
Paroxysmus ILV Master Spellcaster
davethemage
Grandmaster Scribe
Posts: 89
Joined: Sun Aug 09, 2020 2:13 pm

Re: Finding Rune Count from a Runebook in Orion

Post by davethemage »

This is nice! I have a lot of scripts that use runebooks that I can implement this in.
IGN: Edwin Roach
MagicUser
Elder Scribe
Posts: 174
Joined: Mon Nov 03, 2014 2:24 pm
Location: PST

Re: Finding Rune Count from a Runebook in Orion

Post by MagicUser »

Alright so... as promised. Once I figured out a solution, I'd post again. Since the text is unreliable I thought I'd look at the other options and it turns out the buttons are reliable (woot). I looked for and found the pattern. A runebook starts with 50 buttons (0 runes) and then for every left page 5 are added and for every right page 6 are added. I whipped up a nice little piece and stress tested it. It works with duplicates rune names, book not found (though not in bank apparently...?), numeric values, duplicate charges and charges left, full book (regardless of size), failed openings (repeats until success). So no pausing needed! Though the failure still ends up being somewhere around a second of delay. Still, it does it as fast as possible and is reliable.

Code: Select all

/*
 *Description: Find the number of runes a given runebook holds.
 *Parameters: book - The serial of the runebook (String).
 *Returns: runecount - The number of runes (Int).
 */
function getRuneCount(book) {
	var runeCnt = -1;
	
	if (Orion.FindObject(book) != null) {
		//Close any books that might already be open.
		var lastGump = Orion.GetGump(any, '0x554B87F3');
		if (lastGump)
			lastGump.Close();
		
		//Open the book.
		Orion.UseObject(book);
		//Wait for the runebook to open.
		if (Orion.WaitForGump(1000)) {
			//Get the opened books gump.
			var gump = Orion.GetGump(any, '0x554B87F3');
			
			//Find the runecount even if the gump was invalid.
			if (gump !== null && !gump.Replayed())
				runeCnt = processButtonCount(gump.ButtonList().length);
			else
				runeCnt = getRuneCount(book);
			
			//Close book.
			lastGump = Orion.GetGump(any, '0x554B87F3');
			if (lastGump)
				lastGump.Close();
		}
		else {
			runeCnt = getRuneCount(book);
		}
	}
	else {
		Orion.Say("Error: Couldn't find that runebook.");
	}
	
	return runeCnt;
}

/*
 *Description: Find the number of runes based on the button added pattern.
 *Parameters: num - The number of buttons (Int).
 *Returns: counter - The number of runes (Int).
 */
function processButtonCount(num) {
	//There are 50 buttons to start with.
	num -= 50;
	var counter = 0;
	
	//5 buttons added for left page, 6 buttons for right page.
	while (num > 0) {
		num -= 5 + (counter++ % 2);
	}
	
	return counter;
}
As before. Feel free to ask questions or comment.
Respectfully,
Paroxysmus ILV Master Spellcaster
davethemage
Grandmaster Scribe
Posts: 89
Joined: Sun Aug 09, 2020 2:13 pm

Re: Finding Rune Count from a Runebook in Orion

Post by davethemage »

Changes work perfect even with books in an array now! Thanks for the work on this. Will save a lot of time. (now to update all my other scripts to use this)
IGN: Edwin Roach
Post Reply