This probably not correct. You have a number that can only go from 0 to, say, 100, which means your idea of using only one byte (
char) to represent that number is correct, but in reality the game programmers used an
int (or
long), which is why you always have 0’s for the following 3 bytes.
Though if you see those 3 bytes changing to other values I am wrong and you are correct to assign it this way. If they do indeed always stay 0, change it to
unsigned long.
If this is indeed a pointer to another InventorySlot structure, change this to:
- Code: Select all
InventorySlot * PointerToNext;
Am I to look at this like a linked list ?
Yes.
why doesn't the pointer point to the beginning of the next structure ?
If it is indeed not pointing to the actual beginning of the next structure, there is a reason, but in order to understand it you need to know all about class inheritance and virtual functions/overloading.
The short version is that classes can inherit from each other to mean that the first class will be left as it is and the new class will be added to the end of it to add more data and functions.
So in terms of data layout, think of it as the first structure, then at the end of that structure there is another, but they are treated as one big structure. You could still have the first structure without the new one at the end, but in order to have the new one you have to put down the first structure first.
With this layout, a pointer to either type of structure will still be at the very start of the whole thing. The new class is added at the end of the first class, but you won’t have a pointer there where the new class is added. A pointer to the new class will still be at the start of the entire set.
But when virtual functions are involved things are different. Then it becomes important to know where one class ends and the next begins. The way virtual functions work requires that each class/structure start with a pointer to a function table. You make the class/structure in a normal way, but the compiler will put a 4-byte pointer at the start of the class for you. Any pointer to that class points there, so when your new class is added to the first class, a pointer to the new class will point where the new class begins, after the first class.
So if the new class has virtual functions, the new class starts at the end of the first class, with 4 bytes there to be used as the function table pointer for that class, and then all the data inside the new class is added after that.
This is the most common case where pointers point to areas inside a structure rather than at the start of the entire set. When the programmer wants to cast down from the new class to the old class, the compiler generates code that subtracts a certain amount from the pointer, making it correctly point to the start of the first class instead of the new class.
So let’s say your
PointerToNext pointer points to the next structure, but always 14 bytes deep into the structure (which would be where
padding4[20] is inside the structure).
In that case, the real structure layout would look like this:
- Code: Select all
class InventoryBase {
char bAmount;
char padding1[3];
char bModifier;
char bTypeOfItem;
char SlotCharID;
char padding2[1];
char bIdentified;
char padding3[3];
char ItemProperties;
};
class InventorySlot : public InventoryBase {
(4-byte virtual function table pointer here);
char padding4[16]; // Removed 4 bytes to account for the function table pointer.
char bWielded;
char padding5[14];
unsigned long PointerToNext;
char TheRest[20];
virtual void VirtFunc(); // A virtual function inside a class/structure makes the 4-byte table pointer appear at the start, and makes class pointers more complicated.
};
No, you can not do this in my language. There is no need. This is in C++ but you can map this fine with C, and with my language (since it is C).
I am showing a very very rough example of how it would look in C++ just to give an idea of how it would have looked from their end. We do not need to see it this way but if you can understand everything, you can shoot fireballs from your eyes and lightning from your ass (all Japanese can do this already).
I guess that with some simple arithmetic this pointer value could be turned into the beginning of the structure
And it is correct to do so. Since that is what the compiler would do anyway if the original programmer cast it down from the upper class to the lower class.
When you follow PointerToNext, look at where it is inside the structure. That offset in the structure should be another pointer and if you follow it you will get a list of pointers. Each pointer there points to code, so from that list you can follow any of them and see code that is related to that object. Each pointer represents a function that was declared in that class, and all of them accept a “this” pointer as the first parameter.
This is all very powerful to know and understand, because once you know where all those functions are, you can change them to stop decreasing your inventory or whatever you like. You can also use them to find the locations of every instance of InventorySlot structures there are, since the first parameter passed to them will be a pointer to one.
L. Spiro