createpath + getid + getpos together

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Message
Author
User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#61 Post by Bill D Cat » Fri Oct 11, 2013 12:53 pm

I tested this on about a dozen quests in Pioneers Colony and Logar and it worked great. So it has resolved the previous issues and implemented the fly() feature quite well. I think we have a winner here.

(Although, I still count 272 semicolons in the actual createpath.lua file :lol: )

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

Re: createpath + getid + getpos together

#62 Post by rock5 » Fri Oct 11, 2013 1:30 pm

:D Well, I did remove them from the id and comments. I should at least remove them from all the lines it adds to the waypoint file. So when users look at and learn from their new waypoint files, they wont learn the bad habit of using semicolons. :D

And thanks for giving it a good testing.
  • 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#63 Post by Bill D Cat » Sat Oct 12, 2013 7:14 pm

Found a quest where the new QuestByName function crashes. This is repeatable for me over three characters on two servers so far.

Zone: Howling Mountains
Area: Pioneers Colony
NPC: Zily Ante
Quest: Fungus Pet

The function getChoice returns nil for variable "index".
Attachments
QuestByName_Error.jpg

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

Re: createpath + getid + getpos together

#64 Post by rock5 » Sun Oct 13, 2013 12:26 am

That's because that dialog is not the initial dialog where it lists the quests and options. That dialog is the one it shows when you select a quest. I remember now that some npcs do that, they jump straight into the quest. That's why there is no index, because you are just accepting the quest, not selecting the quest from a list.

I don't think that will interfere with anything else so all we have to do is add "if index ~= nil then" to the "OnClick_QuestListButton" lines.

Here is my latest version. The other main thing I changed is to make the getid/pos code only happen 2 times a second and restoring the main loop to 10ms. The setWindowName function was causing high cpu usage for me for the conhost.exe process.
createpath.lua
(28.78 KiB) Downloaded 159 times
The language file hasn't changed.
  • 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#65 Post by Bill D Cat » Sun Oct 13, 2013 2:46 pm

I've successfully used this new version in an effort to re-create my full walk-through of Howling Mountains. So far it has performed perfectly. The only time it crashed was when I was talking to the housemaid and used the QuestByName option to try and sign up for a house instead of using the ChoiceOption key. Overall, I'm feeling really good about how far this has come.

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

Re: createpath + getid + getpos together

#66 Post by rock5 » Sun Oct 13, 2013 10:21 pm

Line 708 was missing it's argument. It should be

Code: Select all

							hf_type = sprintf("ChoiceOptionByName \'%s\'",name)
The only thing that still bothers me about this version is the different way you choose the option between choiceoption and choiceoptionbyname. Example, if the dialog looks like this

Code: Select all

! Accept quest 1
! Accept quest 2

? Complete quest 1

option 1
option 2
If you want to use the ChoiceOption method to choose the second option, you press 2 to select the second option. But if you want to use ChoiceOptionByName you have to choose 5 to select that option. I think having the 2 different ways to select the option is confusing.

The only solution I can think of at the moment is to make the ChoiceOption part of the '-' option. When you select an option using '-' it can ask you if you want to use ChoiceeOption or ChoiceOptionByName. I think that makes it more complex than it needs to be but I can't think of another way to do it 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#67 Post by Bill D Cat » Mon Oct 14, 2013 1:44 am

Does it have to be that complex? I mean if the function determines that it is a ChoiceOption rather than an Accept/CompleteQuest option, can't it just record it into the waypoint the same way option 6 does now? You could attach the name as a comment if you wanted. At least that wouldn't make it language dependent.

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

Re: createpath + getid + getpos together

#68 Post by rock5 » Mon Oct 14, 2013 2:01 am

The problem is each command has it's place. Neither is preferred to the other. ChoiceOption is good if the options don't change or move and it isn't language dependent. ChoiceOptionByName is good if the options might move or change and you can be sure it picks the right option. It can also handle npc options that don't work with ChoiceOption, such as the in-house maids dialog.

I guess most options don't move so in most cases you would use ChoiceOption. But if you use ChoiceOption because you think the options wont change but then they do, it will end up choosing the wrong option. I wish there was a way we could get the language string for the options so we could make ChoiceOptionByName language independent. I haven't thought of a way yet but I'll think on it some more and see if I can come up with something.
  • 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: createpath + getid + getpos together

#69 Post by rock5 » Mon Oct 14, 2013 7:51 am

Well I can quite easily get an options TEXT string from memory but there are 2 main problems with it.

1. Some option texts include substrings. Eg. "I want to be transported to the Varanas Guild Hall". The actual string in memory looks like this "I want to be transported to the [ZONE_VARANAS] Guild Hall". So if I searched in memory for the first string, it wont find it.

2. There can be multiple results for the same text. Of course if the text is the same then it doesn't matter which TEXT string is used but there is always a chance that in some languages they have different text for the different TEXT strings. So it's always best to pick what you think is the right TEXT string. The bot can't automatically do that.

So, even though this has been fun, I'm still not any closer to a solution.

If your interested here is the code I used to get the string from memory. It's just a few commands used with the commandline.

Code: Select all

Command> addressPtrsBase = memoryReadInt(getProc(), addresses.getTEXT)
Command> startloc = memoryReadInt(getProc(), addressPtrsBase + 0x268)
Command> endloc = memoryReadInt(getProc(), addressPtrsBase + 0x26C)
Command> st="Leave conversation" found = findPatternInProcess(getProc(),string.char(0)..st..string.char(0), string.rep("x",#st+2),startloc,endloc) print(memoryReadString(getProc(),found+1)) repeat found = found -1 if memoryReadByte(getProc(), found) == 0 then break end until false print(memoryReadString(getProc(),found+1))
Leave conversation
HOUSE_MAID_LEAVE_TALK
  • 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: createpath + getid + getpos together

#70 Post by rock5 » Tue Oct 15, 2013 5:25 am

Well, this has been fun. I managed to write a search function that can handle the substrings but it took 11s maximum which is too long. I've been tweaking it all day and got it down to about 1.2s. That's not too bad. I'm nearly tempted to add the function to the bot as a compliment to getTEXT but I got the time down to 1.2s by limiting the scan to just strings that start with "SC_" or "SO_" which I believe all the options start with. If I make a more general function that can find all strings, it still takes 6s max which is still too long I think. Plus there really isn't any use for a function except for in createpath. So I might just add the function there.

So with this working I think we could do away with the ChoiceOption altogether. We could move the "ByName" option over to key '6' to replace it.
  • 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#71 Post by Bill D Cat » Tue Oct 15, 2013 2:08 pm

I think I could handle a 2s delay during a createpath session, since I'm usually taking my time while creating the waypoint file anyway. The end result will be a functioning waypoint file that does not have that same delay since the information has already been gathered. And if you think it can effectively combine the two functions into one, then that will free up another key for whatever other option I dream up. :twisted:

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#72 Post by Bill D Cat » Tue Oct 15, 2013 2:24 pm

Bill D Cat wrote:AcceptQuestByName() is easy. The issue lies in CompleteQuestByName() where there are multiple quest rewards to pick from.
Have you looking into a way to detect when multiple quest reward options are offered and possibly prompting the user to select one? ie: CompleteQuestByName(123456,2) I know that I've created waypoints in the past where I forgot to add the second option to pick the reward, and the bot would just brute force its way through accepting the first option.

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

Re: createpath + getid + getpos together

#73 Post by rock5 » Tue Oct 15, 2013 2:36 pm

Forgot about that. Do we want it to detect the popup and then ask which to select? I think that would work.
  • 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#74 Post by Bill D Cat » Tue Oct 15, 2013 2:58 pm

I usually end up putting something like this in my waypoint files to pick based on the character's current primary class. I was originally using the class number for the check, but I think using the text makes it easier to debug later.

Code: Select all

if player.Class1 == CLASS_WARRIOR or player.Class1 == CLASS_KNIGHT then
   CompleteQuestByName(123456,1) -- Chain Armor Option
elseif player.Class1 == CLASS_SCOUT or player.Class1 == CLASS_ROGUE then
   CompleteQuestByName(123456,2) -- Leather Armor Option
elseif player.Class1 == CLASS_MAGE or player.Class1 == CLASS_PRIEST then
   CompleteQuestByName(123456,1) -- Cloth Armor Option
end
The only issue with this type of check at higher levels is if there are some armor sets that you want to complete for a specific class. So editing the waypoint file after the fact to add the extra code isn't really a big deal. I was just wondering if the current version of createpath would have trouble with this type of quest turn in.

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

Re: createpath + getid + getpos together

#75 Post by rock5 » Tue Oct 15, 2013 3:09 pm

I think this is too much. There really is a lot to consider when selecting rewards; weapons, armor and other rewards. It's really the task for a dedicated userfunction but it's not easy, as previous attempts have shown. Just the ability to select an item should do for now. If a user wants to add code to help select the reward they will have to add it later.
  • 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
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#76 Post by Bill D Cat » Tue Oct 15, 2013 5:27 pm

I agree. Detect the pop-up and prompt for which reward to accept is the best option. The user could then even use the insert code option to add a comment about which rewards were offered. Then they could find the IDs of those items and equip them if they want, or just figure out which had the best NPC resale value if they would rather have the gold. I don't think most people will be using the bot like I am to create a full zone walk-through, but it is good to have the ability to do so.

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

Re: createpath + getid + getpos together

#77 Post by rock5 » Tue Oct 15, 2013 10:56 pm

Atually, that's a good point. If you want to change it latter you will need to know what the rewards were. Maybe I can add the rewards to the comment for future reference. Of course we are alread adding the quest name to the comment so it could get crowded. eg

Code: Select all

CompleteQuestByName(123456,1) -- questname -- (cloth hat name), leather hat name, chain hat name, plate hat 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

User avatar
Bill D Cat
Posts: 555
Joined: Sat Aug 10, 2013 8:13 pm
Location: Deep in the Heart of Texas

Re: createpath + getid + getpos together

#78 Post by Bill D Cat » Wed Oct 16, 2013 12:16 am

I'd rather have all the information available like you showed in your example code. It will all get edited anyway before it ever was released to the public. Now if you wanted to truly go overboard, you could include the ID's of the rewards as well :lol: but I have an in-game macro that I use to look it up, so it's not really that important to me. Most of the quest rewards will have sequential IDs, so I can usually tell when I've found the right one if there are more than one item in the game with the same name.

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

Re: createpath + getid + getpos together

#79 Post by rock5 » Wed Oct 16, 2013 12:35 am

To tell you the truth, I haven't started that part of the code yet so I don't know what's possible. I'll let you know when I start on it.

About the function, which I'm calling 'getKeyString()', I think I might add it to the bot as a general function. I've been tidying it up today and realized that I could add optional range arguments so it can be used with createpath and still be fast, and it can be used by users to find key strings for themselves using the whole range.

User would use

Code: Select all

getKeyString("the string")
Which would return a table of matches.

Createpath will use

Code: Select all

getKeyString("the string", true, "SC_", "SP")
Which will return the first match and search from "SC_" to "SP" which will include all "SC_" and "SO_" key strings.

BTW, I'm calling the 2 strings 'key strings' and 'text' to reduce confusion. Eg. "AC_ITEMTYPENAME_0" is the key string and "Weapons" is the text.
  • 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: createpath + getid + getpos together

#80 Post by rock5 » Fri Oct 18, 2013 4:55 am

I think this is the best I'm going to get it.

Code: Select all

function getKeyStrings(text, returnfirst, keytextstart, keytextend)
	local proc = getProc()
	local addressPtrsBase = memoryReadInt(proc, addresses.getTEXT)
	local startloc = memoryReadInt(proc, addressPtrsBase + 0x268)
	local endloc = memoryReadInt(proc, addressPtrsBase + 0x26C)
	local results = {}

	-- Returns the key string of the text found at address 'address'. 'address' points to the 0 before the text.
	local function getkeystr(address)
		repeat
			address = address -1
		until memoryReadByte(proc, address) == 0
		if address < startloc then
			address = startloc
		else
			address = address + 1
		end
		return memoryReadString(proc, address)
	end

	-- Returns nil if no results and prints them if there are results. Only applies to result tables.
	local function getResults()
		if #results == 0 then
			return
		else
			table.print(results)
			return results
		end
	end

	--== First search for an exact match with findPatternInProcess because it's so fast.

	local rangestart = startloc
	local found, tmpkey
	repeat
		found = findPatternInProcess(proc, string.char(0)..text..string.char(0), string.rep("x",#text+2), rangestart, endloc-rangestart);
		if found ~= 0 then
			tmpkey = getkeystr(found)
			if (keytextstart == nil or tmpkey > keytextstart) and (keytextend == nil or keytextend > tmpkey) then
				if returnfirst == true then
					return tmpkey
				else
					table.insert(results, tmpkey)
				end
			end
			rangestart = found + #text+1 -- continue from here to find more matches
			if rangestart >= endloc then break end
		end
	until found == 0

	-- If results found, return them.
	if #results > 0 then
		return getResults()
	end

	--== Now search for text with substrings that match.

	-- Get the start address
	local address = startloc
	if keytextstart then
		address = findPatternInProcess(proc, string.char(0)..keytextstart, string.rep("x",#keytextstart+1), startloc, endloc-startloc)+1;
	end

	local tmpkey, tmptext, tmpstrpat = "","",""
	local translatedSubTEXT
	repeat repeat -- Second 'repeat' is break loop
		-- Get key string and text
		tmpkey = memoryReadString(proc, address) -- key string
		address = address + #tmpkey + 1
		tmptext = memoryReadString(proc, address) -- text
		address = address + #tmptext + 1

		-- end of specified key string range
		if keytextend and tmpkey > keytextend then
			return getResults()
		end

		-- only search key strings with substrings.
		if not string.find(tmptext,"%[") then break end

		-- Skip text with variables, eg. [$var], because they wont match anyway.
		if string.find(tmptext,"%[%$") then break end

		-- Skip text with %s or %d because they wont match anyway.
		if string.find(tmptext,"%%[sd]") then break end

		-- Create find pattern
		tmpstrpat = string.gsub(tmptext,"[%(%)%-%+%*%?]","%%%1") -- prefix special characters with '%'
		tmpstrpat = string.gsub(tmpstrpat,"%[.-%]",".*") -- change substrings to '.*'

		if string.find(tmpstrpat,"%w") and string.find(text, tmpstrpat) then
			for subTEXT in string.gmatch(tmptext,"%[([^%$].-)%]") do
				if tonumber(subTEXT) then -- Must be id
					translatedSubTEXT = GetIdName(tonumber(subTEXT))
				else
					translatedSubTEXT = getTEXT(subTEXT)
				end
				if translatedSubTEXT ~= nil and translatedSubTEXT ~= subTEXT and not string.find(translatedSubTEXT,"%%") then
					tmptext = string.gsub(tmptext, "%["..subTEXT.."%]", translatedSubTEXT, 1)
				end
			end
			if tmptext == text then
				if returnfirst == true then
					return tmpkey
				else
					table.insert(results, tmpkey)
				end
			end
		end
	until true until address >= endloc-1

	return getResults()
end
I had to filter the results a bit to get the speed but it should find most text strings. Exact string matches should be almost instantaneous. Texts that use substrings take about 7s maximum. That's on my system. Createpath will filter the results and use the first result so should take about 1s.

I guess I'll get back to createpath now.
  • 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: No registered users and 1 guest