Page 6 of 6

Re: In-memory inventory

Posted: Wed Sep 29, 2010 6:45 am
by rock5
WOOHOO! WOOT!

I FOUND THE SLOT NUMBERS!



The clue was when I saw in some functions on the rumes of magic wiki (eg. GetBagItemInfo()) they list the slot numbers from 1-257 (I don't know why it accepts 257). So I thought "maybe the slot numbers 1-256 are saved as 0-255 (ie. 00-ff).

So when I minus'ed 1 from the values I was looking for I found it.

So here it is.

It's a static list of byte values starting at 0x9C87A0.
So to get the BagId for the 5th bag slot you would get the value from the 5th address which is 0x9C87A4 and add 1 to it.

So the way it could work is self.BagSlot[slotNumber].SlotNumber can now go back to equaling slotNumber. So when you update an item, you are actually updating the bag slot.

In CPawn:update() you just need to get the BagId first then work out the Address as usual. Very little else has to change. Actually it's so small a job I think I'll do it myself.

Here it is. Initial tests shows everything working. Can someone else please double check it.
MemoryBagIds.zip
(1.07 KiB) Downloaded 179 times
To save you the trouble, here is a bit of code I wrote to print out some inventory info

Code: Select all

<?xml version="1.0" encoding="utf-8"?><waypoints>
<onLoad>
	repeat
		inventory:update()
		for i = 1,60 do
			printf( i .. " " .. inventory.BagSlot[i].SlotNumber .. " " .. inventory.BagSlot[i].BagId .. " " .. tostring(inventory.BagSlot[i].Name) .. "\n")
		end
		player:sleep()
	until false
</onLoad>
</waypoints>

Re: In-memory inventory

Posted: Thu Sep 30, 2010 7:30 am
by Administrator
One thing I noticed is that you put:

Code: Select all

+		bagId = memoryReadByte(proc, addresses.staticBagSlotBagIds + slotnumber - 1) + 1
but don't actually use bagId at all. Instead, you used self.BagId. Am I missing something, or is this a mistake?

Re: In-memory inventory

Posted: Thu Sep 30, 2010 8:59 am
by VoidMain
Administrator wrote:One thing I noticed is that you put:

Code: Select all

+		bagId = memoryReadByte(proc, addresses.staticBagSlotBagIds + slotnumber - 1) + 1
but don't actually use bagId at all. Instead, you used self.BagId. Am I missing something, or is this a mistake?
That is because bagId was the parameter name, it is used after, in:

Code: Select all

		self.BagId = bagId;
All seems to work fine, i'll keep testing during the day.

Re: In-memory inventory

Posted: Thu Sep 30, 2010 8:25 pm
by rock5
I guess I could get rid of bagId altogether and just use;

Code: Select all

self.BagId = memoryReadByte(proc, addresses.staticBagSlotBagIds + slotnumber - 1) + 1
self.Address = addresses.staticInventory + ( ( self.BagId - 61 ) * 68 );

Edit: I just noticed I'm getting errors when the tables are being loaded. Without these changes I don't get the errors. So far I can't figure out what's causing them.

Code: Select all

Loading items tables.
100% [**************************************************]

Table not found for ID: 556049
Wrong value returned in update of item id: 556049
Table not found for ID: 60
Wrong value returned in update of item id: 60
Table not found for ID: 1114636288
Wrong value returned in update of item id: 1114636288

Re: In-memory inventory

Posted: Fri Oct 01, 2010 10:02 pm
by rock5
rock5 wrote:Edit: I just noticed I'm getting errors when the tables are being loaded. Without these changes I don't get the errors. So far I can't figure out what's causing them.
I think I figured it out. It's because most of the bag ids for un-rented bags slots, come back as negative values.

So if we just add "and self.BagId > 0" to line 130 of item.lua it should work.

Code: Select all

	if ( self.Id ~= nil and self.Id ~= oldId and self.Id ~= 0 and self.BagId > 0) then
There are a few things I'm not sure of though.

1. Do the rent bags continue after the first 60 slots? ie. does this work for anyone you has rented bags?
2. What happens if you leave an item in a rent bag once it expires? If the BagId comes up as negative then inventory:update will report it as empty but I noticed the first few unrented slots have positive BagId values. Does that mean inventory:update will successfully update that item even though it is no longer available?

What would be really cool is if we had pointers indicating whether a bag is rented or not. It would be hard to find but maybe you could look up the time remaining. Then you could just update the bags that are available.

Re: In-memory inventory

Posted: Wed Oct 06, 2010 4:02 am
by rock5
After wasting some dias so I could test rented bags Ive fixed some errors and am ready to commit the changes for the slotnumbers fix.

SVN Revision 505

On another note, I've also added the ability to use a table of values with player:findNearestNameOrId(). So it can accept a single value or table of values.
eg.

Code: Select all

player:findNearestNameOrId({"object1 name ", "object2 name"})
So of course you can also use a table for any functions that use findNearestNameOrId.
eg.

Code: Select all

player:target_Object({"object1 name ", "object2 name"}, _waittime, _harvestall, _donotignore)

Re: In-memory inventory

Posted: Wed Oct 06, 2010 7:32 am
by Alkaiser
Excellent! Build 505 seems to be working for me.

Re: In-memory inventory

Posted: Thu Oct 07, 2010 1:53 am
by rock5
I forgot to mention that I have pointers for if the rent bags are rented or not. The values hold the rent time in minutes or 0xFFFFFFFF if not rented.

Rent bag 1 address 9C930C
Rent bag 2 address 9C9310
Rent bag 3 address 9C9314
Rent bag 4 address 9C9318

I'm not sure how to implement them though.

I thought maybe we could add;
inventory.RentBag[n].Rented = true or false
inventory.RentBag[n].RentTime = minutes or 0

Or maybe just;
inventory.RentBag[n] = minutes or false

Then of course a lot of functions need to be edited to avoid unrented bags.

How does that sound?