Error RoMScript returned values

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Post Reply
Message
Author
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Error RoMScript returned values

#1 Post by rock5 » Fri Apr 16, 2010 11:57 am

I'm trying to write an in-game function to return all the quest names in the quest book to speed up some quest functions I'm writing but I've encountered a problem.

Taking igf_GetTooltip as a guide I wrote in my MyFunction addon.;

Code: Select all

function igf_getQuestList()
	local qq={}
    for i=1,30 do
        __, __, name = GetQuestInfo(i)
		qq[i] = name or " "
		pr(qq[i]) -- Debug
    end

    return qq[1], qq[2], qq[3], qq[4], qq[5], qq[6], qq[7], qq[8], qq[9], qq[10],
	qq[11], qq[12], qq[13], qq[14], qq[15], qq[16], qq[17], qq[18], qq[19], qq[20],
	qq[21], qq[22], qq[23], qq[24], qq[25], qq[26], qq[27], qq[28], qq[29], qq[30]
end


In a waypoint file I wrote;

Code: Select all

	local qq={}
	qq[1], qq[2], qq[3], qq[4], qq[5], qq[6], qq[7], qq[8], qq[9], qq[10],
	qq[11], qq[12], qq[13], qq[14], qq[15], qq[16], qq[17], qq[18], qq[19], qq[20],
	qq[21], qq[22], qq[23], qq[24], qq[25], qq[26], qq[27], qq[28], qq[29], qq[30]
	=RoMScript("igf_getQuestList()")
	for i=1,20 do
		print(qq[i])
	end
When the in-game function executes it correctly prints all the quests names and blanks for the rest but after RoMScript
recieves its values it prints about 11 quests and nil for the rest. I even did some tests with igf_GetTooltip and it looks like it also only recieves some of the lines and the rest are nil.

Is there some sort of limitation to RoMScript or is it just not behaving the way it's supposed to?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#2 Post by rock5 » Fri Apr 16, 2010 12:31 pm

Had a bit of a look at RoMScript function and I think I understand.

The results are written to macro2 and read by rombot. Macros have a character limitation so that is why it doesn't get all the returned values.

Is there anyway around this problem?

I'm not sure how rombot communicates with the client but maybe you could have the macro break the output into 255 character pages and send them 1 at a time. Or if that is too much for a macro maybe you could use an in-game function that handles the communication. Or maybe you could just send the output to more than 1 macro, although that would be a crude solution that would likely over-write other macros.

Is a fix possible?

ps. Sorry for keeping you so busy.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#3 Post by rock5 » Fri Apr 16, 2010 12:52 pm

On second thought I've moved the whole 'check quest status' function to in-game so all it has to do is return the status.

Accepting a quest with my old function took 8 seconds. Now it only takes 4.

Yay!
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Error RoMScript returned values

#4 Post by Administrator » Fri Apr 16, 2010 4:26 pm

Ok, sounds good. I will answer your questions, anyways, for others that might be interested in doing something similar. If possible, it would be better to run this type of loop in the in-game addon, then query information out of it (simply put, store the results in global variables [assumed to be anything that's not local], then you can use it in RoMScript).

There is a 256-byte (including NULL terminator) limit on macros. Judging by the Macro.bsd file, it looks like they intended to actually increase this limit to 1024 bytes eventually.

Alternatively, to get around this limit, you could handle each quest independently. This could be slower, but I wouldn't expect by much.

You can also increase your speed by breaking out of that for loop when a nil value is reached (ie. reached the end of the quest list; no point trying to continue reading information).

I'm not sure how rombot communicates with the client but maybe you could have the macro break the output into 255 character pages and send them 1 at a time.
This would cause extra code to have to be sent with each RoMScript call, further limiting the amount of actual, usable code you can pass in and slowing it down. It's usually not needed, either, so it would seem inefficient to do this. Not a bad idea, though. Worth considering.
ps. Sorry for keeping you so busy.
Don't worry about it. That's what the forums are for.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#5 Post by rock5 » Sat Apr 17, 2010 4:26 am

I thought it was working but it's not. Can you see anything wrong with this code?

The ingame function;

Code: Select all

function igf_IsQuestDone(questname)
    local c = 1
    local __, __, name = GetQuestInfo(c)
	while name ~= nil do
		if string.find(name, questname) then -- Quest exists
            if string.find(name,"(Complete)") then -- Quest complete
                pr("c1 = ".. c) -- pr is my print command
                return true
            else -- Quest not complete
                pr("c2 = ".. c)
                return false
            end
        end
        c=c+1
        __, __, name = GetQuestInfo(c)
    end
	pr("c3 = ".. c)
    return
end
The rombot userfunction;

Code: Select all

function Quest.Done(questname)
	local result =RoMScript("igf_IsQuestDone("..questname..")")
	print("igf_IsQuestDone(\""..questname.."\") = " .. (result or "nil"))
	return result
end
The waypoint onload code;

Code: Select all

	<onLoad>
		settings.profile.mobs = {"Kaa Marcher"};
		changeProfileOption("LOOT_DISTANCE", 75)
		local action ="local state= Quest.Done('Kaa Marchers Must Die');print(state); if state ~= false then  __WPL:setWaypointIndex(12) end"
		settings.profile.events.onLeaveCombat = loadstring(action)
	</onLoad>
What happens is, after leaving combat, the print statement in Quest.Done() prints the following;

Code: Select all

igf_IsQuestDone("Kaa Marchers Must Die") = ♠lectric Shock
It should only return true, false or nil.

Also none of the print statements in the ingame function execute so it looks as if it doesn't even run.

Hope you can help.

ps. I remember there was an external program that allowed you to create macros using the full 1024 bytes. Maybe that means you could find a way to use the full 1024 for output? It was called Rom Macro Editor but I'm not sure if it would still work or if it can be found anymore.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Error RoMScript returned values

#6 Post by Administrator » Sat Apr 17, 2010 5:06 am

Looks like a bug with RoMScript. Try changing lines 517-518 of functions.lua from:

Code: Select all

	"} for i=1,#a do if a[i] then r=r..tostring(a[i])" ..
	" end r=r..'" .. string.char(9) .. "' end" ..
To:

Code: Select all

	"} for i=1,#a do r=r..tostring(a[i])" ..
	" r=r..'" .. string.char(9) .. "' end" ..
At line 582, add:

Code: Select all

			if( readsz == "nil" ) then readsz = nil; end;

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#7 Post by rock5 » Sat Apr 17, 2010 5:49 am

Nothing changed, but now I'm getting a lot of "empty or wrong bagid return" messages.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Error RoMScript returned values

#8 Post by Administrator » Sat Apr 17, 2010 7:25 am

Try taking out this line (which I previously told you to add):

Code: Select all

         if( readsz == "nil" ) then readsz = nil; end;
That should resolve it. It seems to work just fine with nil values like this.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#9 Post by rock5 » Sat Apr 17, 2010 9:03 am

Administrator wrote:Try taking out this line (which I previously told you to add):

Code: Select all

         if( readsz == "nil" ) then readsz = nil; end;
That should resolve it. It seems to work just fine with nil values like this.
The 'empty or wrong bagid return' errors have stopped but it still returns gibberish. Sometimes though it returns nil.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#10 Post by rock5 » Tue Apr 20, 2010 4:00 pm

Any progress on this yet?
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: Error RoMScript returned values

#11 Post by Administrator » Tue Apr 20, 2010 7:17 pm

It works fine for me.

In functions.lua, line 516:

Code: Select all

	local text = "/script r='' a={" .. script ..
	"} for i=1,#a do r=r..tostring(a[i])" ..
	" r=r..'" .. string.char(9) .. "' end" ..
	" EditMacro(2,'',7,r);";
Addon:

Code: Select all

function igf_IsQuestDone(questname)
    local c = 1
    local __, __, name = GetQuestInfo(c)

   while name ~= nil do
      if string.find(name, questname) then -- Quest exists
			pr("Name:" .. name);
			
            if string.find(name,"(Complete)") then -- Quest complete
                pr("c1 = ".. c) -- pr is my print command
                return true
            else -- Quest not complete
                pr("c2 = ".. c)
                return false
            end
        end
        c=c+1
        __, __, name = GetQuestInfo(c)
    end
   pr("c3 = ".. c)
    return
end
Profile action script:

Code: Select all

		local val = RoMScript("igf_IsQuestDone('Posting')");

		printf("Quest val: %s\n", tostring(val));
It prints out 'Quest val: true' for quests that are complete, and 'Quest val: false' for those that are not.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Error RoMScript returned values

#12 Post by rock5 » Wed Apr 21, 2010 7:36 am

It's been a dog of a day.

After doing some initial simple tests everything was looking good, but when I tried to make practical use in my Kaa Marcher daily script, I encountered one problem after another. No sooner had I fixed one problem, that I noticed another. At 1 point I even had my rom client crashing every time I ran the script. I literally took all day ironing out all the bugs.

Anyway, everything seems to be running smoothly now. I even added string.lower for the find statements so it's now case insensitive. I toyed with the idea of moving the 'complete' and 'accept' quest functions ingame but there is no way to pause I believe.

So here are, what I believe, are my final scripts. Thanks Administrator for all your help and hard work.

Just so you know they allow you to check, accept and complete quests by name pretty much without fail. It doesn't even matter if the npc dialog opens directly to a accept/complete dialog or gives you a quest list. I created these because I was getting fed up with waypoint files going awry because it failed to accept or complete a quest.

Hopefully it will be of use to others.

In game function:

Code: Select all

------------------------------------------------
-- igf_IsQuestDone Script
-- questname = name of quest
-- returns 'true' if quest complete 'false' if not and nil if not accepted
------------------------------------------------
function igf_IsQuestDone(questname)
	questname=string.lower(questname)
    local c = 1
    local __, __, name = GetQuestInfo(c)
	while name ~= nil do
		if string.find(string.lower(name), questname) then -- Quest exists
            if string.find(name,"(Complete)") then -- Quest complete
                return true
            else -- Quest not complete
                return false
            end
        end
		c = c + 1
        __, __, name = GetQuestInfo(c)
    end
    return
end
RoMBot functions:

Code: Select all

Quest={}

------------------------------------------------
-- Quest.Accept script
-- Accepts a quest by name even if it automatically opens
-- questname = name of quest
-- returns 'true' if you now have the quest 'false' if not
------------------------------------------------
function Quest.Accept(questname)
    -- First check if already accepted
	if Quest.Done(questname) ~= nil then
		return true
	else
		-- Maybe quest already open. Try AcceptQuest. Couldn't hurt.
		sendMacro("AcceptQuest()"); yrest(1500)
	end

    -- Check again
	if Quest.Done(questname) ~= nil then
		return true
	else
		questname=string.lower(questname)
		-- Try to find and accept
		counter = 1
		while RoMScript("GetQuestNameByIndex(1,".. counter..")") do
			if string.find(string.lower(RoMScript("GetQuestNameByIndex(1,".. counter..")")),questname) then
				sendMacro("OnClick_QuestListButton(1,".. counter..")");  yrest(1500);
				sendMacro("AcceptQuest()"); yrest(1500)
				break
			end
			counter = counter + 1
		end
	end

	if Quest.Done(questname) ~= nil then
		return true
	else
		print("Failed to accept quest. Accept manually then press DELETE."); player:sleep();
		-- Check if user accepted quest manually
		if Quest.Done(questname) ~= nil then
			return true
		end
	end
	return false
end

------------------------------------------------
-- Quest.Complete script
-- Completes a quest by name even if it automatically opens
-- questname = name of quest
-- reward = reward number for completed quests that need to select a reward
-- returns 'false' if quest is still ready to be completed but we failed to complete
-- returns 'true' if quest successfully accepted or not need to complete
------------------------------------------------
function Quest.Complete(questname,reward)
    -- First check if already accepted
	if Quest.Done(questname) == nil then
		print("Quest has not been accepted yet. Or maybe you have auto accept addon?")
		return true -- not need to complete
	elseif Quest.Done(questname) == false then
		print("Cannot complete quest because conditions for quest not meet yet.")
		return true -- not need to complete
	else -- Quest is ready to be completed
		-- Maybe quest already open. Try CompleteQuest. Couldn't hurt.
		if reward then
			sendMacro("SpeakFrame_ClickQuestReward(SpeakQuestReward1_Item"..reward..")")
			yrest(500)
		end
		sendMacro("CompleteQuest()"); yrest(1500)

		-- Check again
		if Quest.Done(questname) ~= true then
			return true
		else
			questname=string.lower(questname)
			-- Try to find and complete
			counter = 1
			while RoMScript("GetQuestNameByIndex(3,".. counter..")") do
				if string.find(string.lower(RoMScript("GetQuestNameByIndex(3,".. counter..")")),questname) then
					sendMacro("OnClick_QuestListButton(3,".. counter..")");  yrest(1500);
					if reward then
						sendMacro("SpeakFrame_ClickQuestReward(SpeakQuestReward1_Item"..reward..")")
						yrest(500)
					end
					sendMacro("CompleteQuest()"); yrest(1500)
					break
				end
				counter = counter + 1
			end
		end

		if Quest.Done(questname) ~= true then
			return true
		else
			print("Failed to complete quest. Complete manually then press DELETE."); player:sleep();
			-- Check if user accepted quest manually
			if Quest.Done(questname) ~= true then
			else
				return true
			end
		end
		return false
	end
end

------------------------------------------------
-- Quest.Done Script
-- questname = name of quest
-- returns 'true' if quest complete 'false' if not and nil if not accepted
------------------------------------------------
function Quest.Done(questname)
	return RoMScript("igf_IsQuestDone(\'"..questname.."\')")
end
To use, just use Quest.Done() to get the status of a quest, Quest.Accept() to accept a quest by name and Quest.Complete() to complete a quest by name.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 158 guests