View previous topic :: View next topic |
Author |
Message |
Gryphyn
Joined: 20 Jan 2005 Posts: 431
|
Posted: Thu Jan 20, 2005 6:00 Post subject: |
|
|
I'll ask the question, as no one else seems to have...
This will enable a 'container' object to be store/retrieved with all it's contents, right? So you can have a truly persistant chest, just by saving the 'chest' object.
Or do we have issues with the uniqueness of 'object' identifiers/instances in-game?
Cheers
Gryphyn |
|
Back to top |
|
|
Blacksting
Joined: 03 Jan 2005 Posts: 107
|
Posted: Thu Jan 20, 2005 8:28 Post subject: |
|
|
The idea of "containers" is a tricky subject. The answer you seek is no. Chests can not be "saved" as one object. Chests are placeables and there corresponding toolset file .utp is not a valid file that can be passed with Save and Retrieve (in fact... I think ... the engine does not even try to pass the information.)
If you save an "inventory" container (i.e. bag,box) the contents will be saved. Here you run in to a logic problem though with the NWN Engine. Since you are saving something in Inventory you are more than likely running a loop to find that container. A "loop" of inventory will provide you with the container object but also all of the items in that container will be identified by the loop as well.
The result: saving a container inventory object inside a container placeable with a loop will duplicate the items in the container (they are saved twice... once in the bag and once as an individual item ALSO in the placeable.) My solution has been to dump all items in a container in to the placeable container OnInventoryDisturbed. That means no neat organization in bags, unfortunately, inside a persistent chest. The trade-off is to run a VERY cycle intensive script that goes something like this:
cycle 1 through inventory identifying containers
cycle through the items found in the containers (a nested Get Item loop) and save it as local object on the chest as "contained"
cycle 2 through all inventory again matching the object against the "list" created
if not on the list save it
Personally with the Bio DB saving being slow I opted out of having the "saving" script do more than it was already doing. However, now that the DBase DB part is taken out of the equation the "inventory cycling" method of bag checks is not out of the realm of possibility again as a viable solution. |
|
Back to top |
|
|
Alosynth
Joined: 06 Jan 2005 Posts: 24
|
Posted: Fri Jan 21, 2005 2:28 Post subject: |
|
|
How about a merchant store object? Would that work using the sco/rco on just the store itself, and therefore saving not only the inventory, but also the information relating to gold levels the merchant has. Or, would we still have to pass all items that go into and come out of the store to and from the databse? |
|
Back to top |
|
|
Senalaya
Joined: 29 Dec 2004 Posts: 82 Location: Germany
|
Posted: Fri Jan 21, 2005 2:32 Post subject: |
|
|
Bioware's SCO/RCO is limited to items and creatures, obviously so has to be a function, that hooks into them.
The only trick you could do, is to use a creature and place the items in it's inventory. The creature will be stored or retrieved, with all items and local variables included, in a single operation. |
|
Back to top |
|
|
Senalaya
Joined: 29 Dec 2004 Posts: 82 Location: Germany
|
Posted: Fri Jan 21, 2005 3:11 Post subject: |
|
|
Blacksting wrote: | ...
cycle 1 through inventory identifying containers
cycle through the items found in the containers (a nested Get Item loop) and save it as local object on the chest as "contained"
cycle 2 through all inventory again matching the object against the "list" created
if not on the list save it
...
|
There is a simpler solution for that:
Code: | int nSkip = 0;
object oItem = GetFirstItemInInventory(oContainer);
object oLoop;
while (GetIsObjectValid(oItem))
{
StoreItem(oItem);
if (GetHasInventory(oItem))
{
// count items in the inventory
oLoop = GetFirstItemInInventory(oItem);
while (GetIsObjectValid(oLoop))
{
nSkip++;
oLoop = GetNextItemInInventory(oItem);
}
// skip the following nSkip items (the items alrady saved with the container appear directly after the container again)
while (nSkip > 0)
{
nSkip--;
oItem = GetNextItemInInventory(oContainer);
}
}
oItem = GetNextItemInInventory(oContainer);
}
|
or a bit shorter, but less descriptive:
Code: | object oItem = GetFirstItemInInventory(oContainer);
object oLoop;
object oCurrentItem;
while (GetIsObjectValid(oItem))
{
StoreItem(oItem);
if (GetHasInventory(oItem))
{
oCurrentItem = oItem;
oLoop = GetFirstItemInInventory(oCurrentItem);
while (GetIsObjectValid(oLoop))
{
oItem = GetNextItemInInventory(oContainer);
oLoop = GetNextItemInInventory(oCurrentItem);
}
}
oItem = GetNextItemInInventory(oContainer);
}
|
|
|
Back to top |
|
|
Blacksting
Joined: 03 Jan 2005 Posts: 107
|
Posted: Fri Jan 21, 2005 7:39 Post subject: |
|
|
I was not aware that the items in the container are "directly" after the container in the parent's inventory 100 percent of the time. Are you certain that this happens without fail? |
|
Back to top |
|
|
Senalaya
Joined: 29 Dec 2004 Posts: 82 Location: Germany
|
Posted: Fri Jan 21, 2005 10:13 Post subject: |
|
|
Blacksting wrote: | I was not aware that the items in the container are "directly" after the container in the parent's inventory 100 percent of the time. Are you certain that this happens without fail? |
I use that algorithm on our server for more than a year. No problems at all.
It's asured due to the GFF datastructure and it's list system. |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Jan 21, 2005 17:57 Post subject: |
|
|
Please discuss topis not directly related to ODBC2 in a separate thread. _________________ Papillon |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Jan 21, 2005 18:00 Post subject: |
|
|
Ok, after spending the whole f*cking day to find out why people have problems, while others have not, I've come to the following conclusion: None.
I have even got access to a computer that exhibits the problematic behaviour, and after a lot of trial and error, I found out that ODBC2 and NWserver do not play along nicely when ODBC2 allocates memory dynamically (i.e. malloc()).
I compiled a new version that allocated its memory for object exchange statically (1 MB) and it seems to work without crashes on my test computer. I am not sure why, but it looks like as if mallloc'ed memory in one DLL does not play well with malloc'ed memory in another code section (nwserver). That is the cause for the RtlFreeHeap error, btw.
What I DID find out is that dynamic memory allocation works on Windows XP Service Pack 2, while it does not work on Service Pack 1!
Well anyway, grab the updated version
http://nwnx.org/fileadmin/user_upload/nwnx_odbc_0922-test.zip
and try it out ! Your feedback will significantly add to my (currently very damped) motivation. _________________ Papillon
Last edited by Papillon on Fri Jan 21, 2005 18:22; edited 2 times in total |
|
Back to top |
|
|
Makzimia De Graf
Joined: 31 Dec 2004 Posts: 55 Location: San Diego CA.
|
Posted: Fri Jan 21, 2005 18:08 Post subject: |
|
|
Pap, Salandra said yes, that is what her call on it would be, she also said, you may want to consider that 1MB allocation statically is not big enough for large modules, especially ones using a lot more data in memory like ours definitely does. That is her words, I presume you know where she is headed with it. _________________ Makzimia De Graf
DM/Creator Island of Fredian
fredian.game-host.org:5123
Forums at http://castille.us/fredian/Forums |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Jan 21, 2005 18:15 Post subject: |
|
|
Salandra ? _________________ Papillon |
|
Back to top |
|
|
Makzimia De Graf
Joined: 31 Dec 2004 Posts: 55 Location: San Diego CA.
|
Posted: Fri Jan 21, 2005 18:17 Post subject: |
|
|
Salandra is my wife and an Oracle and database been at it 19 yrs in general specialist, she did all the table work for our database systems in the beginning as well. So, she understands why it isn't working right at the moment, even if I don't . _________________ Makzimia De Graf
DM/Creator Island of Fredian
fredian.game-host.org:5123
Forums at http://castille.us/fredian/Forums |
|
Back to top |
|
|
Senalaya
Joined: 29 Dec 2004 Posts: 82 Location: Germany
|
Posted: Fri Jan 21, 2005 18:24 Post subject: |
|
|
Are you sure, that it's the malloc() of nwnx_odbc that causes the trouble? Or could it be the memory allocation of the intergrated MySQL/SQLite libaries?
I havn't had any crashes with the ODBC part. |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Jan 21, 2005 18:25 Post subject: |
|
|
Well, prove me wrong, but I doubt that anyone has objects larger than 1 MB in size. This is per object. I could increase it to 10 MB, but that would probably just eat up 9,5MB memory without any benefit. Anyway, it is just a test to see if it helps the ones experiencing crashes. _________________ Papillon |
|
Back to top |
|
|
Makzimia De Graf
Joined: 31 Dec 2004 Posts: 55 Location: San Diego CA.
|
Posted: Fri Jan 21, 2005 18:26 Post subject: |
|
|
Senelaya, yes, my point on another thread was that ODBC way is working nicely, MySQL direct route, minus the ODBC driver, crashes. _________________ Makzimia De Graf
DM/Creator Island of Fredian
fredian.game-host.org:5123
Forums at http://castille.us/fredian/Forums |
|
Back to top |
|
|
|