createpath + getid + getpos together

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

Re: createpath + getid + getpos together

#101 Post by rock5 » Wed Nov 20, 2013 3:02 am

Well of course it can't be used exactly like that because although 123456 is a number <s>123456 is a syntax error. It could be a string, eg

Code: Select all

GetIdName("<s>123456")
but then it would have to parse the string to get the "<s>" and the id number. And it's not like it would make things simpler. You would still have to have a separate check for it

Code: Select all

		elseif tonumber(subKeyString) then -- Must be id
			translatedSubTEXT = GetIdName(tonumber(subKeyString))
		elseif subKeyString:sub(1,3) =="<S>" then -- Must be id plural
If you then did GetIdName(subKeyString), it would then have to do the work of parsing the string. Wait, it would still have to parse it to get the id. I guess it could be done but I don't think it's intuitive. If you have an id you would get the plural like this

Code: Select all

single = GetIdName(id)
plural = GetIdName("<S>"..id)
Which looks like its the wrong way to do it to me. Whereas if the syntax was GetIdName(id, plural) you would do

Code: Select all

single = GetIdName(id)
plural = GetIdName(id, true)
I don't want to use a separate function because otherwise it would be repeating similar code and if I decide to have it return the shortnote as well then it saves it being repeated 3 times.

Anyway, still thinking about it. I sometimes don't rush into things but instead take my time thinking of the best way to do something before I even begin.
  • 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

#102 Post by Bill D Cat » Thu Nov 21, 2013 3:19 am

I did some playing around with the GetIdName() function and got this to work. I noticed that some of the items do not have a plural form of the name defined, and will return an empty string "" for them. So I've added a fallback check to use the singular form of the name in those cases. I'll leave it to you to modify the getTEXT() function to parse for the "<S>".

Code: Select all

-- Returns the name for a given id
function GetIdName(itemId,plural)
	plural = plural or false
	if plural == true then pluralOffset = 4 else pluralOffset = 0 end
	if itemId ~= nil and itemId > 0 then
		local itemAddress = GetItemAddress(itemId)
		if itemAddress ~= nil and itemAddress > 0 then
			local name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset + pluralOffset, 0)
			if name == "" and plural then
				name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0)
			end
			if name == nil then
				-- Item data not totally substantiated yet. Do "GetCraftRequestItem", then the address will exist.
				if RoMScript then RoMScript("GetCraftRequestItem("..itemId..", -1)") end
				local name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset + pluralOffset, 0)
				if name == "" and plural then
					name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0)
				end
			end
			return name
		end
	end
end

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

Re: createpath + getid + getpos together

#103 Post by rock5 » Thu Nov 21, 2013 7:06 am

A couple of points first. In this case "plural = plural or false" doesn't seem to do anything. You only really need to know if plural is true or not true so you could leave that out. Also you made pluralOffset a global variable. Should be local.

I've been doing some work to make it return card and recipe names. I've got it working but have been taking my time to get it just right. I'm still not 100% happy with it. Now I'll have to merge these changes and I just have to figure out what order is best to do everything. I don't even know if the GetCraftRequestItem code is needed for plurals.
  • 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

#104 Post by Bill D Cat » Thu Nov 21, 2013 12:14 pm

Sorry, I'm just a bit impatient :-)

Code: Select all

	if not keystring or type(keystring) ~= "string" then return end
	local resultTEXT = memoryGetTEXT(keystring)
	for subKeyString in string.gmatch(resultTEXT,"%[(.-)%]") do
		local translatedSubTEXT
		if subKeyString:sub(1,1) == "$" then -- variable. See if it's player.
			if subKeyString == "$PLAYERNAME" or subKeyString == "$playername" then
				translatedSubTEXT = player.Name
			end
		elseif tonumber(subKeyString) then -- Must be id
			translatedSubTEXT = GetIdName(tonumber(subKeyString))
		elseif subKeyString:sub(1,3) == "<S>" then -- Must be id plural
			translatedSubTEXT = GetIdName(tonumber(subKeyString:sub(4,9)),true)
		else
			translatedSubTEXT = memoryGetTEXT(subKeyString)
		end
		if translatedSubTEXT ~= nil and translatedSubTEXT ~= subKeyString and not string.find(translatedSubTEXT,"%%") then
			resultTEXT = string.gsub(resultTEXT, "%["..subKeyString.."%]", translatedSubTEXT)
		end
	end
And as for making the pluralOffset value a local variable, I get an error when I add the local keyword, so I just left off for now:

Code: Select all

if plural == true then pluralOffset = 4 else pluralOffset = 0 end  -- This works

if plural == true then local pluralOffset = 4 else local pluralOffset = 0 end --This gives the error below

11:04am - ...les (x86)/MicroMacro/scripts/rom/classes/memorytable.lua:126: attempt to perform arithmetic on global 'pluralOffset' (a nil value)

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

Re: createpath + getid + getpos together

#105 Post by rock5 » Thu Nov 21, 2013 2:00 pm

Where you put the local made it local to the if statement. You have to declare it outside the if statement first so it will be local to the function.

Code: Select all

local pluralOffset
if plural == true then pluralOffset = 4 else pluralOffset = 0 end
  • 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

#106 Post by Bill D Cat » Thu Nov 21, 2013 3:14 pm

While looking through the string_enus.db file, I noticed one other embeded variable that may nor may not need to be parsed. The format looks like [123456|Some Text] where the text is usually some other form of the name, such as a possessive form. I didn't notice too many in quest text strings, and most looked like they were going to be displayed in a yellow "warning" message or banner text.

Code: Select all

SC_101501_07="[101501|Yusalien's] hardened skin slowly resumes its original state again."

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

Re: createpath + getid + getpos together

#107 Post by rock5 » Thu Nov 21, 2013 10:36 pm

I noticed them too. I think it's sort of an override. So the id is for showing a link to the npc and the override is the text it shows. I think the reason most of them are possessive names is because that is the most common need for it. Here is an example of one that has nothing to do with the name.

Code: Select all

SC_424995_1 = "Is this true? It's hard to believe that the [119682|Commander] is so concerned about us. I will have to work harder to fulfill my duties!"
119682 is Shar Talos so I assume thats the commander. I could add a filter for that too.

On another note, I think I will be adding a cache for the getTEXT returned results. So it only looks up a keystring once and saves it to a table so subsequent calls will be faster.
  • 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

#108 Post by Bill D Cat » Thu Nov 21, 2013 11:11 pm

Simple enough to filter I suppose. If you wanted the normal ID you could use:

Code: Select all

elseif tonumber(subKeyString:sub(1,6)) and subKeyString:sub(7,7) == "|" then -- Id with a text override
     translatedSubTEXT = GetIdName(tonumber(subKeyString:sub(1,6)))
And if you wanted the override text:

Code: Select all

elseif tonumber(subKeyString:sub(1,6)) and subKeyString:sub(7,7) == "|" then -- Id with a text override
     translatedSubTEXT = subKeyString:sub(8,#subKeyString)
The question is, which would be more useful? I'm guessing the override text, as that would be what the game would display. I'll do some more investigating after work to see if I can find any that show up in clickable dialog options. Otherwise it probably won't matter which way we handled it.

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

Re: createpath + getid + getpos together

#109 Post by rock5 » Thu Nov 21, 2013 11:22 pm

Well if it shows the override text then that is what we would have to use to get a string match.
  • 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

#110 Post by Bill D Cat » Thu Nov 21, 2013 11:28 pm

Yeah, the more I think about it, the more I agree that the override text is the way to go. It's not just clickable links that you may have to worry about. Setting up a message monitoring event for certain system messages may encounter one of these strings as well. I have to remind myself to think outside of the scope that I'm using the bot and to consider how others may want to use it. I'll make it as a developer eventually :lol:

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

Re: createpath + getid + getpos together

#111 Post by rock5 » Fri Nov 22, 2013 1:24 am

I hope you do. The problem is I have a real hard time letting go of my control. It's real hard for me to let others slowly work things out on their own without stepping in and taking over and writing or rewriting things myself. I was lucky when I first came in. Administrator had already lost interest in the bot and no previous developers remained. At first it was just me pestering the Administrator with my ideas. Then later when I got better at programming, I would offer my ideas as already written code. Then eventually Administrator just gave me developer access to the svn. I think the reason I've lasted so long as a developer is because I don't have a life. :D
  • 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

#112 Post by Bill D Cat » Fri Nov 22, 2013 3:45 am

Don't worry, I don't want to take over this project, just be a contributor of (hopefully) good ideas. I too have a life, but I like to spend what free time I have coding. I do a lot of programming at work, so it sort of carries over into my personal time. I just hope I've been able to help others from time to time, and to bring a fresh perspective on things that can be added to, or expanded upon with this project. The changes I've posted to getTEXT() and GetIdName() are allowing my current waypoint project to move ahead much more smoothly. Having the translated strings will allow the waypoints to truly be language independent and usable by more people without needing modifications.

My time spent in RoM these days is not to advance one character to the maximum, but rather to pass time doing something I enjoy. And right now, I am enjoying the self-given challenge to script as many of the zones in their entirety as I possibly can.

1. Elven Island - Done, though being improved upon now.
2. Yrvandis Hollows - Done, only refining the elite fight remains.
3. Howling Mountains - Single class quests done, working on quests that are only available after you take your second class.
4. Coast of Opportunity - All quests in and around Heffner Camp done. Will cross the river soon.
5. Sascilia Steppes - All quests leading up to Rose Caravan done.

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

#113 Post by Bill D Cat » Fri Nov 22, 2013 4:20 am

Here's where my code additions are right now:

functions.lua, line 2388:

Code: Select all

	if not keystring or type(keystring) ~= "string" then return end
	local resultTEXT = memoryGetTEXT(keystring)
	for subKeyString in string.gmatch(resultTEXT,"%[(.-)%]") do
		local translatedSubTEXT
		if subKeyString:sub(1,1) == "$" then -- variable. See if it's player.
			if subKeyString == "$PLAYERNAME" or subKeyString == "$playername" then
				translatedSubTEXT = player.Name
			end
		elseif tonumber(subKeyString) then -- Must be id
			translatedSubTEXT = GetIdName(tonumber(subKeyString))
		elseif subKeyString:sub(1,3) == "<S>" then -- Must be id plural
			translatedSubTEXT = GetIdName(tonumber(subKeyString:sub(4,9)),true)
		elseif tonumber(subKeyString:sub(1,6)) and subKeyString:sub(7,7) == "|" then -- Id with a text override
			translatedSubTEXT = subKeyString:sub(8,#subKeyString)
		else
			translatedSubTEXT = memoryGetTEXT(subKeyString)
		end
		if translatedSubTEXT ~= nil and translatedSubTEXT ~= subKeyString and not string.find(translatedSubTEXT,"%%") then
			resultTEXT = string.gsub(resultTEXT, "%["..subKeyString.."%]", translatedSubTEXT)
		end
	end
memorytable.lua, line 120:

Code: Select all

-- Returns the name for a given id
function GetIdName(itemId,plural)
	local pluralOffset
	if plural == true then pluralOffset = 4 else pluralOffset = 0 end
	if itemId ~= nil and itemId > 0 then
		local itemAddress = GetItemAddress(itemId)
		if itemAddress ~= nil and itemAddress > 0 then
			local name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset + pluralOffset, 0)
			if name == "" and plural then
				name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0)
			end
			if name == nil then
				-- Item data not totally substantiated yet. Do "GetCraftRequestItem", then the address will exist.
				if RoMScript then RoMScript("GetCraftRequestItem("..itemId..", -1)") end
				name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset + pluralOffset, 0)
				if name == "" and plural then
					name = memoryReadStringPtr(getProc(), itemAddress + addresses.nameOffset, 0)
				end
			end
			return name
		end
	end
end

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

Re: createpath + getid + getpos together

#114 Post by rock5 » Sat Nov 23, 2013 12:33 am

I've made a real effort today to wrap my head around how everything is supposed to come together. It's more complex than you might think. Consider this; What if you are looking for a plural of a card or recipe? First we would get the npc or item id. First question, do we use the plural of the mob or item to make the name? Some recipes actually have names and plurals so we don't have to get the item and make the name. One of them at least doesn't have a plural. So in fact we have to check the name first. If it doesn't have a name then we check if it's a card or recipe then make the name.

So basically we are saying; check the plural, if no plural then check the singular, if no singular then, check if card or recipe, if card or recipe check plural, if no plural check singular.

I've decided to simplify it. The only time I can see plurals being used is for the getTEXT strings. So I did a search for "[<s>55" and "[<s>77" and came up with no results. So I'm going to just return the singular if I have to look up a recipe item or card mob.

So the logic will be; check the plural, if no plural then check the singular, if no singular then check if card or recipe, if card or recipe then return the singular.

And another thing, I think if the plural address is 0x902EFC, then it doesn't have a plural name and returns "". That means that if the game calls for that items plural it will get "". If it's used in a key string it will have "". That means if our function returns the singular then the string wont match. I'd assume that anywhere in the game that calls for a plural of an id then that id will have a plural. So there shouldn't be any need to return the singular of an id if it doesn't have a plural. Of course it might be possible that the game also returns the singular if it doesn't have a plural but we don't have any evidence of that.

And then there is the issue of the GetCraftRequestItem command in the GetIdName function and when it's necessary. It only runs if the name read is initially nil. If the name address is 0x902EFC then the name returned is "" GetCraftRequestItem doesn't run. I think name is initially nil only if the name address is 0 but I can't be 100% sure. According to this post http://www.solarstrike.net/phpBB3/viewt ... 530#p25530 it needs it because sometimes the name address is "missing". I'm not 100% sure what I meant by missing. I believe the area where all the strings are are always there so if the name address is an address I'm assuming it will point to a string. So I'm assuming the only way the name would be nil is if the address = 0.

Feel free to comment but just writing it all down helped to clarify it in my mind. I'll be going to a party soon so I wont get much more done now but I will work on it after I get back.
  • 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

#115 Post by Bill D Cat » Sat Nov 23, 2013 12:20 pm

rock5 wrote:I've made a real effort today to wrap my head around how everything is supposed to come together. It's more complex than you might think. Consider this; What if you are looking for a plural of a card or recipe? First we would get the npc or item id. First question, do we use the plural of the mob or item to make the name? Some recipes actually have names and plurals so we don't have to get the item and make the name. One of them at least doesn't have a plural. So in fact we have to check the name first. If it doesn't have a name then we check if it's a card or recipe then make the name.
From what I've seen in the .fdb files, the plural of "Recipe - Hero Potion" would be listed as "Recipes - Hero Potion", so you would use the singular form of the item to create the plural form of the Recipe. I'm just having trouble coming up with a situation where the game would use the plural form of Card or Recipe in the first place.
rock5 wrote:So basically we are saying; check the plural, if no plural then check the singular, if no singular then, check if card or recipe, if card or recipe check plural, if no plural check singular.
Again, is there a case where the plural form would be used in-game, or is this just so the bot user could have the data for their own use?
rock5 wrote:I've decided to simplify it. The only time I can see plurals being used is for the getTEXT strings. So I did a search for "[<s>55" and "[<s>77" and came up with no results. So I'm going to just return the singular if I have to look up a recipe item or card mob.

So the logic will be; check the plural, if no plural then check the singular, if no singular then check if card or recipe, if card or recipe then return the singular.
I agree. Until such time as someone comes across a string that uses the plural form, the singular should be sufficient.
rock5 wrote:And another thing, I think if the plural address is 0x902EFC, then it doesn't have a plural name and returns "". That means that if the game calls for that items plural it will get "". If it's used in a key string it will have "". That means if our function returns the singular then the string wont match. I'd assume that anywhere in the game that calls for a plural of an id then that id will have a plural. So there shouldn't be any need to return the singular of an id if it doesn't have a plural. Of course it might be possible that the game also returns the singular if it doesn't have a plural but we don't have any evidence of that.
Good point. As above, until it is needed, we can always just comment out the fallback code or remove it.
rock5 wrote:And then there is the issue of the GetCraftRequestItem command in the GetIdName function and when it's necessary. It only runs if the name read is initially nil. If the name address is 0x902EFC then the name returned is "" GetCraftRequestItem doesn't run. I think name is initially nil only if the name address is 0 but I can't be 100% sure. According to this post http://www.solarstrike.net/phpBB3/viewt ... 530#p25530 it needs it because sometimes the name address is "missing". I'm not 100% sure what I meant by missing. I believe the area where all the strings are are always there so if the name address is an address I'm assuming it will point to a string. So I'm assuming the only way the name would be nil is if the address = 0.
Perhaps a different sanity check would be all that is required here. I'll do some test runs later with some extra print statements to see if I can get it to trigger the GetCraftRequestItem command. Who knows if some other changes in the bot and/or game itself has modified that behavior since the time of that last post.

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

Re: createpath + getid + getpos together

#116 Post by rock5 » Sat Nov 23, 2013 11:04 pm

Bill D Cat wrote:Perhaps a different sanity check would be all that is required here. I'll do some test runs later with some extra print statements to see if I can get it to trigger the GetCraftRequestItem command. Who knows if some other changes in the bot and/or game itself has modified that behavior since the time of that last post.
Ok but let me explain the process as I understand it.

There are 2 GetCraftRequestItem commands. One is in GetItemAddress and one in GetIdName.

The one in GetItemAddress runs when the item area hasn't been created yet and the id in the id list has 0 where it should be pointing to the item area. When we run GetCraftRequestItem it creates the item area and it's address appears in the id list. This ones easy to trigger. Just access a new random id for the first time.

The one in GetIdName only runs if the item area was created but not completed and is missing the name address. GetCraftRequestItem wouldn't have run in GetItemAddress otherwise the address would exist. I suspect it only creates these partial item areas in special situations. Maybe for particular types of ids so I would check out different types of ids.
  • 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

#117 Post by rock5 » Sun Nov 24, 2013 12:39 am

So I guess the current logic is; if it asks for a plural give it the plural, if it asks for a singular give it the singular, if there is no singular and it's a card or recipe make the name from the item/npc id.

You know most recipes and all cards don't have names so for all of them the above logic will cause it to read the name address of that id needlessly. And seeing as no cards or recipes are used in key string text, I'm thinking of ignoring those few recipes that have names and go directly to the item id to make the name. I'm not even sure those names are used anyway. They could just be a mistake from some inexperienced dev.

So in that case the logic would be; if the id is a card or recipe then switch to the item/npc id and add the correct prefix to the name, then get the name of that id and add it to the name using the plural if it's specified. I don't see a problem with using the plural even on recipes and cards because I can't envision any situation in which a plural of them will ever be asked for.
  • 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

#118 Post by rock5 » Sun Nov 24, 2013 3:36 am

Ok this is what I have for GetIdName, finally.

Code: Select all

-- Returns the name for a given id
function GetIdName(itemId, plural)
	-- Check itemId
	if itemId == nil or itemId == 0 then
		return
	end

	-- Check plural
	local pluralOffset
	if plural == true then pluralOffset = 4 else pluralOffset = 0 end

	-- Get and check item address
	local itemAddress = GetItemAddress(itemId)
	if itemAddress == nil or itemAddress == 0 then
		return
	end

	-- If card or recipe, update itemId, itemAddress and prefix name
	local name = ""
	if itemId >= 770000 and itemId <= 772000 then
		itemId = memoryReadInt( getProc(), itemAddress + addresses.idCardNPCOffset );
		itemAddress = GetItemAddress( itemId );
		name = getTEXT("SYS_CARD_TITLE")	-- "Card - "
	elseif itemId >= 550000 and itemId <= 553000 then
		itemId = memoryReadInt( getProc(), itemAddress + addresses.idRecipeItemOffset );
		itemAddress = GetItemAddress( itemId );
		name = getTEXT("SYS_RECIPE_TITLE")	-- "Recipe - "
	end

	-- Get name/plural address
	local nameaddress = memoryReadInt(getProc(), itemAddress + addresses.nameOffset + pluralOffset)
	if nameaddress == 0 and RoMScript then
		RoMScript("GetCraftRequestItem("..itemId..", -1)")
		nameaddress = memoryReadInt(getProc(), itemAddress + addresses.nameOffset + pluralOffset)
	end

	name = name .. memoryReadString(getProc(), nameaddress)

	return name
end
I'm pretty happy with it.

Now to do some work on getTEXT. Let me see, you already added things like text overrides and plurals. I'm going to add a cache. Oops I just found an unusual string

Code: Select all

Sys102145_shortnote = "The treasure robbers died hungry and poor. The cold they felt before they died eventually became the [<S>101390|Frozen Shade's] deadliest weapon."
That's both a plural and override. I can't see why they would do that. So the pattern will need a little tweaking. I don't think '|' is used in subtext for anything else but overrides so we could probably just do a string.find for that.
  • 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

#119 Post by rock5 » Sun Nov 24, 2013 4:03 am

You might have noticed in the function above that I changed the whole format of the function. The way I changed it is more like the way we code in the bot. To make things clearer, instead of writing something like this;

Code: Select all

function name()
    if a == value then
        if b == value then
            if c == value then
                -- do something
            end
        end
    end
end
We try to write it like this

Code: Select all

function name()
    -- Check the a value
    if a ~= value then
        return
    end

    -- Check the b value
    if b ~= value then
        return
    end

    -- Check the c value
    if c ~= value then
        return
    end

    -- do something
end
It does exactly the same thing but is super clear and easier to maintain than nested ifs and makes it easy to comment each step. This is the main thing I learnt working with the bot.
  • 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

#120 Post by rock5 » Sun Nov 24, 2013 8:53 am

This is what my getTEXT looks like.

Code: Select all

local getTEXTTable = {}
function getTEXT(keystring)
	if not keystring or type(keystring) ~= "string" then return end
	if getTEXTTable[keystring] then
		return getTEXTTable[keystring]
	end

	local function memoryGetTEXT(str)
		local addressPtrsBase = memoryReadInt(getProc(), addresses.getTEXT)
		local startloc = memoryReadInt(getProc(), addressPtrsBase + 0x268)
		local endloc = memoryReadInt(getProc(), addressPtrsBase + 0x26C)
		local quarter = math.floor((endloc-startloc) / 4)

		-- Pattern doesn't work with first string so check that first
		if str == "AC_ITEMTYPENAME_0" then
			return memoryReadString(getProc(), startloc + 18)
		end

		local tmpStart = endloc
		local tmpEnd = endloc
		-- Find which quarter of memory holds string to speed up search
		for count = 1,3 do
			tmpStart = tmpStart - quarter
			local found = findPatternInProcess(getProc(), string.char(0).."Sys", "xxx", tmpStart, tmpEnd);
			local tmpText = memoryReadString(getProc(), found + 1)
			if tmpText <= str then
				startloc = tmpStart
				break
			else
				endloc = tmpStart
			end
		end

		local searchlen = endloc - startloc
		local pattern = string.char(0x00) .. str .. string.char(0x00)
		local mask = string.rep("x", #pattern)
		local offset = #pattern
		local found = findPatternInProcess(getProc(), pattern, mask, startloc, searchlen);
		if found ~= 0 then
			return memoryReadString(getProc(), found + offset)
		else
			return str
		end
	end

	local resultTEXT = memoryGetTEXT(keystring)
	
	-- Replace known sub key strings
	for subKeyString in string.gmatch(resultTEXT,"%[(.-)%]") do
		local translatedSubTEXT
		if subKeyString:sub(1,1) == "$" then -- variable. See if it's player.
			if subKeyString == "$PLAYERNAME" or subKeyString == "$playername" then
				translatedSubTEXT = player.Name
			end
		elseif tonumber(subKeyString) then -- Must be id
			translatedSubTEXT = GetIdName(tonumber(subKeyString))
		elseif subKeyString:find("|",1,true) then -- Id with a text override
			translatedSubTEXT = subKeyString:match(".*|(.*)")
		elseif subKeyString:sub(1,3) == "<S>" then -- Must be id plural
			translatedSubTEXT = GetIdName(tonumber(subKeyString:sub(4,9)),true)
 		else
			translatedSubTEXT = memoryGetTEXT(subKeyString)
		end
		if translatedSubTEXT ~= nil and translatedSubTEXT ~= subKeyString and not string.find(translatedSubTEXT,"%%") then
			resultTEXT = string.gsub(resultTEXT, "%["..subKeyString.."%]", translatedSubTEXT)
		end
	end

	-- Remember result
	if resultTEXT ~= keystring then
		getTEXTTable[keystring] = resultTEXT
	end

	return resultTEXT
end
  • 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