Aller au contenu

Photo

Troublesome stores


  • Veuillez vous connecter pour répondre
30 réponses à ce sujet

#1
Greyfort

Greyfort
  • Members
  • 234 messages
when useing StoreCampaignObject funtion with stores I seem to be getting either the objects are invalid or they are valid yet no DB writen with the following script.  I am tired and it is 15 mins tell christmas perhaps i should stop for the night...

//:: Script Name: zz_clr_store
//::
//:: Orginal Authors: Idea , TritonX "pshop_OnOpenDialogue"
//:: Script created by Old Man`s Beard, June 2006
//:: Thanks to Lex and UOAbigail for their support
//::
//:: EDITED/ALTERED: Greyfort
//::
//:: Created: 12.24.2010
//::
//:: Script Function:
//:: transfer store1 DB info to store2 haveing 0 duplicates
//:: from store1 into store2.  Then clean out store1 db
//::
////////////////////////////////////////////////////////////////////////////////

/* //uncoment these if you dont have the include and remove the include line
//:://///////////////////////////////////////////////////////////
// Use to load a stores data base with nwn db
void OHS_LoadStore(object oStore, string sDBName);

void OHS_LoadStore(object oStore, string sDBName)
{
  location lStore = GetLocation(oStore);
  int bLoaded = GetLocalInt(oStore,"OHS_STORE_LOADED");
  if (GetIsObjectValid(oStore) && !bLoaded)
  {
    int nItems = GetCampaignInt(sDBName,"N_ITEMS");
    PrintString(IntToString(nItems)+" in "+sDBName);
    object oItem;
    int ILRStackSize, nChargesStarting;
    int nNth;
    for (nNth=1; nNth<=nItems; nNth++)
    {
      oItem = RetrieveCampaignObject(sDBName,"ITEM_"+IntToString(nNth),GetLocation(oStore),oStore);
      if (GetPlotFlag(oItem) )// || GetStolenFlag(oItem)) remove // to Destroy Plot and Stolen Items
      {
        DestroyObject(oItem);
      }
      else
      {
        ILRStackSize = StringToInt(Get2DAString("baseitems","ILRStackSize",GetBaseItemType(oItem)));
        SetItemStackSize(oItem,ILRStackSize);
        nChargesStarting = StringToInt(Get2DAString("baseitems","ChargesStarting",GetBaseItemType(oItem)));
        if (nChargesStarting>0) SetItemCharges(oItem,nChargesStarting);
        // SetInfiniteFlag(oItem,TRUE); //Uncomment if you want stackable to be infinite
      }
    }
    SetLocalInt(oStore,"OHS_STORE_LOADED",TRUE);
  }
}//needed end of function
///////////////////////////////////////////////////////////////////////////////
*/ //uncoment these if you dont have the include and remove the include line

// includes here  //
#include "zz_store_inc"
void main()
{
// this script is executed by a NPC
// NPC Stationary merchant Executing script, store and DB tag
object oNPC_Merch=OBJECT_SELF;//GetObjectByTag("stat_merch");
//debug line
PrintString(GetTag(oNPC_Merch)+" executing script");
//debug line

if (GetObjectType(oNPC_Merch) == OBJECT_TYPE_CREATURE && GetIsObjectValid(oNPC_Merch ) )
{
//debug line
PrintString("NPC valid in executing script");
//debug line

//Stationary merchant store and DB tag
object oStore=GetObjectByTag("stat_merch");
string sDBName="stat_merch";
string sStoreTag1=GetLocalString(OBJECT_SELF,"sStoreTag");

// Traveling merchant store and DB tag
object oStore2=GetObjectByTag("trvl_merch");
string sDBName2="trvl_merch";
string sStoreTag2=GetLocalString(OBJECT_SELF,"sTrvStoreTag");
int nItems2 = GetCampaignInt(sDBName2,"N_ITEMS");

object oItem;
object oItemChk;
int nNth = 0;//nItems2;
////////////////////////////////////////////////////
// first set items in traveling merchant db

  oStore2 = GetObjectByTag("OHS_STORE");
  if ( GetIsObjectValid(oStore2)==FALSE )
  {
    oStore2 = CreateObject(OBJECT_TYPE_STORE,"trvl_merch",GetLocation(OBJECT_SELF));
      if (GetObjectType(oStore2) == OBJECT_TYPE_STORE)
        { //was(oStore, "OHS_PERSISTENT_STORE") replaced with sStoreTag
        OHS_LoadStore(oStore2,sStoreTag2);

  if (GetIsObjectValid(oStore2))
  {
  //debug line
  PrintString(sDBName2+" valid saving items in inventory to DB");
 //debug line
    DestroyCampaignDatabase(sDBName2);
    oItem = GetFirstItemInInventory(oStore2);
    while (GetIsObjectValid(oItem))
    {
      StoreCampaignObject(sDBName2,"ITEM_"+IntToString(++nNth),oItem);
        //debug line
        string sItemName= GetName(oItem);
        PrintString(sItemName+"= ITEM_"+IntToString(++nNth)+"saved to DB");
        //debug line
        oItem = GetNextItemInInventory(oStore2);
    }//end of while
    SetCampaignInt(sDBName2,"N_ITEMS",nNth);
  }//end of if
        }
  }
/////////////////////////////////////////////////////////////////
// then store stationary merchants items in db
// removing any items that may be duplicates befor putting items
// in traveling merchants inventory

  oStore = GetObjectByTag("OHS_STORE");
  if ( GetIsObjectValid(oStore)==FALSE )
  {                               //replace "resrefofyourstore" by one in your palette
    oStore = CreateObject(OBJECT_TYPE_STORE,"stat_merch",GetLocation(OBJECT_SELF));
      if (GetObjectType(oStore) == OBJECT_TYPE_STORE)
        { //was(oStore, "OHS_PERSISTENT_STORE") replaced with sStoreTag
        OHS_LoadStore(oStore,sStoreTag1);

  if (GetIsObjectValid(oStore))
  {
  //debug line
  PrintString(sDBName+" valid saving items in inventory to DB");
  //debug line
    oItemChk = GetFirstItemInInventory(oStore2);
    while (GetIsObjectValid(oItemChk))
    {
    oItem = GetFirstItemInInventory(oStore);
        while (GetIsObjectValid(oItem))
        {
            if(oItem == oItemChk)
            {
            DestroyObject(oItem);
            }else{
                StoreCampaignObject(sDBName2,"ITEM_"+IntToString(++nNth),oItem);
                //debug line
                string sItemName= GetName(oItem);
                PrintString(sItemName+"= ITEM_"+IntToString(++nNth)+"saved to DB");
                //debug line
                }
        oItem = GetNextItemInInventory(oStore);
        }//end of while oItem
    oItem = GetNextItemInInventory(oStore2);
    }//end of while oItemChk
   SetCampaignInt(sDBName2,"N_ITEMS",nNth);
  }//end of if
        }
  }
// clean out NPC Stationary merchant store
//DestroyCampaignDatabase(sDBName);

// }else{PrintString("merchants invalid"); }


}else {PrintString("NPC not valid "); }
//////////////////////////////
}// end of script


If you all see what im missing please let me know...Perhaps its the campain objects?  I even tried OMB loadstore etc after all thats what got me working on it LOL

MERRY CHRISTMAS!!!

Modifié par Greyfort, 25 décembre 2010 - 08:33 .


#2
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
I have not read or figured out the whole script.  At a quick glance however I saw this:

...
StoreCampaignObject(sDBName2,"ITEM_"+IntToString(++nNth),oItem);
        //debug line
        string sItemName= GetName(oItem);
        PrintString(sItemName+"= ITEM_"+IntToString(++nNth)+"saved to DB");
...


You are increaseing   nNTH  twice every time you go through the loop.

 
EDIT:
You did the same thing again with your debug  lower in the script.

 }else{
                StoreCampaignObject(sDBName2,"ITEM_"+IntToString(++nNth),oItem);
                //debug line
                string sItemName= GetName(oItem);
                PrintString(sItemName+"= ITEM_"+IntToString(++nNth )+"saved to DB");
                //debug line


Most likely all you need to do is get rid of the var increment(++ ) in your debug lines.

Modifié par Lightfoot8, 25 décembre 2010 - 09:03 .


#3
Greyfort

Greyfort
  • Members
  • 234 messages
Another Question about stores and using the nwn db can I useing data base commands move campain objects from one merchant to another? If I can't then thats my issue with the script I think. so if anyone knows thankyou.

#4
Greyfort

Greyfort
  • Members
  • 234 messages
Forgive me once again...Can anyone validate that you absolutely can not move one CampaignObject in a store to another store. i'm still having issues, and I can't help but wonder am I trying to do something you just cant do.



example:

move CampaignObjects from store A to store B(make sure no duplicate items from storeA in store B if so destroy them) then clear store A



is it the merchants that are giveing me the problem or the fact I'm storeing CampaignObjects. Any clarity on this would be very helpful.

#5
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
I thing the problem here and why you are not getting any responces, is that the question make no since. At least it dosent make any since to me.



A CampaignObject is data stored out in a data base. When you retrive it you can place it in any store you want to place it in.



As far as moving a CampaignObject from one store to another. Well a store can not contain a DB to beging with. A store being either a blueprint or an instance of the blueprint in the game.



In short I really have no Idea what you are asking.

#6
Greyfort

Greyfort
  • Members
  • 234 messages
Forgive me that my question does not make since to you. I was having a issue with merchants or so it seemed. I took the campaign data base and loaded it into a chest for each store then went through the chests checking to make sure no duplicate items and only storing one of the item. etc.



This worked and now merchant loads up new data base, when I have got the bugs out i will post what i am trying to do so it will be clear.



I was inspired by Fester Pot link:

http://nwvault.ign.c....Detail&id=3074



It loads a DB into a store, then when store closes it save to db

I got it to work and it works well the merchant always has what you sold them.



My current issue is comparing DBs so I only have 1 of a item and no duplicates, I was trying to do it with merchants and having issues

#7
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Code repost from PM:
// includes here //
#include "zz_store_inc"
//::///////////////////////
void main() {

    object oItemA, oItemB, oItem1, oItem2;
    
    object oChest=GetObjectByTag("swap_chest");
    object oChest1=GetObjectByTag("swap_chest1");
    object oChest2=GetObjectByTag("swap_chest2");
    
    string sDBName;// = GetTag(oStore);
    int nNth = 0;
    
    string sStoreTag1="stat_merch";
    string sStoreTag2="trvl_merch";

    if (GetIsObjectValid(oChest1)) {
        //:: clear chest
        oItemA = GetFirstItemInInventory(oChest1);
        while (GetIsObjectValid(oItemA)) {
            DestroyObject(oItemA);
            oItemA = GetNextItemInInventory(oItemA);
        }
        
        //:: clear chest end
        OHS_LoadStore(oChest1,sStoreTag1);
        DestroyCampaignDatabase("stat_merch");//(sDBName);
    }

    if( GetIsObjectValid(oChest2)==TRUE ) {
        //:: clear chest
        oItemB = GetFirstItemInInventory(oChest2);
        while (GetIsObjectValid(oItemB)) {
            DestroyObject(oItemB);
            oItemB = GetNextItemInInventory(oItemB);
        }
        
        //:: clear chest end
        OHS_LoadStore(oChest2,sStoreTag2);
        DestroyCampaignDatabase("trvl_merch");//(sDBName);
    } 
/*
    check items in oChest2 vs oChest1
    destroy any items from oChest1 that oChest2 has
    store only oChest2 items
*/
    if( GetIsObjectValid(oChest)) {
        string sTag;
        sDBName="trvl_merch";
        oItem2 = GetFirstItemInInventory(oChest2);
        
        while (GetIsObjectValid(oItem2)) {
            oItem1=GetFirstItemInInventory(oChest1);
            sTag = GetTag(oItem1);
            while(GetIsObjectValid(oItem1)) {
                // check for duplicate destroy them
                if(sTag == GetTag(oItem2)) {
                    SetLocalInt(oItem1, "Destroyed", 1);
                    DestroyObject(oItem1);
                }    
                oItem1 = GetNextItemInInventory(oChest1);    
            }
    
            // stores item from chest2 to "trvl_merch" sDBName
            StoreCampaignObject(sDBName,"ITEM_"+IntToString(++nNth),oItem2);
            oItem2 = GetNextItemInInventory(oChest2);
        }
    }

    if (GetIsObjectValid(oChest)) {

        // NOW store oChest1 items
        oItem1 = GetFirstItemInInventory(oChest1);
        while (GetIsObjectValid(oItem1)) {
            // stores item from chest1 to
            //"trvl_merch" sDBName
            if (!GetLocalInt(oItem1, "Destroyed"))//store them unless they are slated for destruction as duplicates
                StoreCampaignObject(sDBName,"ITEM_"+IntToString(++nNth),oItem1);
            oItem1 = GetNextItemInInventory(oChest1);
        }

        //"trvl_merch" sDBName
        SetCampaignInt(sDBName,"N_ITEMS",nNth);
    }
}


#8
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
ok, There are a few logic errors and oversights in the code above. I don't have time to fully go over it right now. But here is what I see so far.  

The first one I am not 100% on my self,  The GetFirst/next functions are iterators, You may be running into a problem with nesting them.

The Object oChest is checked two times to see if it is a valid object but is never used outside of that.
 
DestroyObject  does not destroy an object until after the current script finishes running.

Of the four basic sections in your script. only the last one tries to hand this correctly, by checking if the local int 'destroyed' is set on the object before storing it in the DB. 

The First two loops never handle the problem at all, They never set the int.

the third section, that compares the items, Does set the int on objects, that it sets for destruction, But it never checks the int to see if the item was already marked destroyed so it can ignore it.
   

oversite: 
If thees are chests objects you are dumping the items into.  Or even if they are stores.  With the fact that none of the items are destroyed before adding the stored campaign objects from the database into them, means that the container can easily overflow, having the  items end up on the ground and not in the chest at all. This is of course more of a problem for the chest then the store.  but is a possible problem for either one.

Modifié par Lightfoot8, 01 janvier 2011 - 07:54 .


#9
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

Lightfoot8 wrote...

Of the four basic sections in your script. only the last one tries to hand this correctly, by checking if the local int 'destroyed' is set on the object before storing it in the DB. 

The First two loops never handle the problem at all, They never set the int.

The int was my addition, actually - an example of how to deal with DO's built-in delaycommand. I think you're correct that the other DO's need them as well. I'll go ahead and add them for him.

I don't think the iterators are a problem, as they are iterating over two separate lists of objects. I did briefly consider writing a custom function to check for duplicate tags, but I didn't want to add more functions, since the above was only one of two given to me in somewhat of a jumble.

Funky

#10
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Sorry for the delay in posting. Just got my first look at the OHS include above, which also appears to use delays. Will have to further untangle this mess - nevermind that it appears to be intended for a store, not a chest.... ><



Funky

#11
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Here's the updated code - not compiled, but should work (not sure where that include at the top belongs, if anywhere - I think OHS_LoadStore was in it?


// includes here //
#include "zz_store_inc"
//::///////////////////////

void OHS_LoadStore(object oStore, string sDBName) {
    location lStore = GetLocation(oStore);
      int bLoaded = GetLocalInt(oStore,"OHS_STORE_LOADED");
      if (GetIsObjectValid(oStore) && !bLoaded) {
          
        int nItems = GetCampaignInt(sDBName,"N_ITEMS");
        PrintString(IntToString(nItems)+" in "+sDBName);
        object oItem;
        int ILRStackSize, nChargesStarting;
        int nNth;
        for (nNth = 1; nNth <= nItems; nNth++) {
              oItem = RetrieveCampaignObject(sDBName,"ITEM_"+IntToString(nNth),GetLocation(oStore),oStore);
              if (GetPlotFlag(oItem)) {// || GetStolenFlag(oItem)) remove // to Destroy Plot and Stolen Items
                SetLocalInt(oItem, "Destroyed", 1);
                DestroyObject(oItem);
              } else {
                ILRStackSize = StringToInt(Get2DAString("baseitems","ILRStackSize",GetBaseItemType(oItem)));
                SetItemStackSize(oItem,ILRStackSize);
                nChargesStarting = StringToInt(Get2DAString("baseitems","ChargesStarting",GetBaseItemType(oItem)));
                if (nChargesStarting>0) 
                    SetItemCharges(oItem,nChargesStarting);
                // SetInfiniteFlag(oItem,TRUE); //Uncomment if you want stackable to be infinite
              }
        }
        SetLocalInt(oStore,"OHS_STORE_LOADED",TRUE);
      }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void main() {

    object oItemA, oItemB, oItem1, oItem2;
    
    object oChest = GetObjectByTag("swap_chest");
    object oChest1 = GetObjectByTag("swap_chest1");
    object oChest2 = GetObjectByTag("swap_chest2");
    
    string sDBName;// = GetTag(oStore);
    int nNth = 0;
    
    string sStoreTag1="stat_merch";
    string sStoreTag2="trvl_merch";

    if (GetIsObjectValid(oChest1)) {
        //:: clear chest
        oItemA = GetFirstItemInInventory(oChest1);
        while (GetIsObjectValid(oItemA)) {
            SetLocalInt(oItemA, "Destroyed", 1);
            DestroyObject(oItemA);
            oItemA = GetNextItemInInventory(oItemA);
        }
        
        //:: clear chest end
        OHS_LoadStore(oChest1,sStoreTag1);
        DestroyCampaignDatabase("stat_merch");//(sDBName);
    }

    if (GetIsObjectValid(oChest2)) {
        //:: clear chest
        oItemB = GetFirstItemInInventory(oChest2);
        while (GetIsObjectValid(oItemB)) {
            SetLocalInt(oItemB, "Destroyed", 1);
            DestroyObject(oItemB);
            oItemB = GetNextItemInInventory(oItemB);
        }
        
        //:: clear chest end
        OHS_LoadStore(oChest2,sStoreTag2);
        DestroyCampaignDatabase("trvl_merch");//(sDBName);
    } 
/*
    check items in oChest2 vs oChest1
    destroy any items from oChest1 that oChest2 has
    store only oChest2 items
*/
    if (GetIsObjectValid(oChest)) {
        string sTag, sTag2;
        sDBName = "trvl_merch";
        oItem2 = GetFirstItemInInventory(oChest2);
        
        while (GetIsObjectValid(oItem2)) {
            sTag = GetTag(oItem2);
            oItem1 = GetFirstItemInInventory(oChest1);
            while (GetIsObjectValid(oItem1)) {
                // check for duplicate destroy them
                if (sTag == GetTag(oItem1)) {
                    SetLocalInt(oItem1, "Destroyed", 1);
                    DestroyObject(oItem1);
                }    
                oItem1 = GetNextItemInInventory(oChest1);    
            }
    
            // stores item from chest2 to "trvl_merch" sDBName
            if (!GetLocalInt(oItemB, "Destroyed"))
                StoreCampaignObject(sDBName,"ITEM_"+IntToString(++nNth),oItem2);
            oItem2 = GetNextItemInInventory(oChest2);
        }
    }

    if (GetIsObjectValid(oChest)) {

        // NOW store oChest1 items
        oItem1 = GetFirstItemInInventory(oChest1);
        while (GetIsObjectValid(oItem1)) {
            // stores item from chest1 to
            //"trvl_merch" sDBName
            if (!GetLocalInt(oItem1, "Destroyed"))//store them unless they are slated for destruction as duplicates
                StoreCampaignObject(sDBName,"ITEM_"+IntToString(++nNth),oItem1);
            oItem1 = GetNextItemInInventory(oChest1);
        }

        //"trvl_merch" sDBName
        SetCampaignInt(sDBName,"N_ITEMS",nNth);
    }
}

I still have a few lingering doubts about this, thogh. First of all, it appears to allow the storage of plot and stolen items, only removing them after they've been stored, which makes no sense at all given the speed of the bioware database. Second, it automatically maximizes stacksize and charges, which could lead to a problem of exploitation. Third, and most importantly, however, is that I'm still not sure what it is you're trying to accomplish here. This is a common problem when you ask how to code something before you ask what it is you should code. ;) Because of that, I can't say with any certainty that it will actually accomplish what you're trying to do.

Funky

Modifié par FunkySwerve, 01 janvier 2011 - 11:10 .


#12
Birdman076

Birdman076
  • Members
  • 186 messages
Greyfort was trying to assist me in making a travelling merchant who will take player based items sold to stores as opposed to deleting them with a clear store script. It would be nice to keep the items in play so to speak. The travelling merchant would have only one of each item so the store inventory doesn't fill and cause problems with lag, etc. Ideally it would be nice to have multiple travelling merchants who would specialize in different types of items (jeweler, armor smith, weapon smith, magical merchant, etc). Thank you to everyone who has helped thus far, it is greatly appreciated.

#13
Greyfort

Greyfort
  • Members
  • 234 messages
Thankyou for all the insight Funky and lightfoot, i was going a bit crazy. I haven't tested it I will give it a try. What realy stumped me was the delay on the destroying objects, I had never ran into that issue before. Forgive me for chainging it to chests, it is intened for stores and i thought maybe merchants where my problem but I confused lightfoot (sorry light).



I thought about a checking for duplicate function also, thought that would be a good idea still think it is. If you have a function handy i would surely use it.

Thanks again both of you.


#14
Greyfort

Greyfort
  • Members
  • 234 messages
Ok tested your very last script, it did as i poorly described. It only wrote one of any Item into the store2 DB and cleared store1 db. Now i just have to try it with stores not chest just as described above. Cant have a bunch of chests around what will players think..

#15
Greyfort

Greyfort
  • Members
  • 234 messages
I did run into one issue, and that had to do with my orginal script and my logic as Lightfoot said...I was only checking one db not both, so script works to move items from store1 to store2 with no duplicates. But store 2 has duplicates IE: store had bullets I sold more bullets tested script and store has two stacks of 99. If you do have a duplicate checking function Fuzzy I could use it.

My issue is now checking store2 orginal DB vers new one. So let me re ask before i script as you said. Rather then do all this with placeables/merchants...

Q1)using no objects(chests/stores) can I just compare DB's example: Loads(by compaing data we have the max nuber items in db to call for data from DB) store1 db save data as “store1_temp_DB” loads store2 DB save data as “store2_temp_DB”, Looks for duplicates in both temp dbs creating “store2_new_DB”. Then compare “store2_temp_DB” vs store2_new_DB creating final DB “trvl_merch”

Q2) im sure above is possible but it seems must be done with a object inventories is that correct? Thats the issue I face with the nwn DB, I’m use to using nwnx2 extender with ms access comparing just the data.

Q3) So what Im trying to do as Birdman076 said is make a clean store script that transfers items to a traveling merchant useing the nwnDB wich im having problems with. perhaps its the blurry eyed state i’m in buy the time RL gives me a break.

Any help, ideas would be wonderful.
Thanks again funky for “Third, and most importantly, however, is that I'm still not sure what it is you're trying to accomplish here. This is a common problem when you ask how to code something before you ask what it is you should code.;)

I’m not the best at articulating some times.

Modifié par Greyfort, 02 janvier 2011 - 09:06 .


#16
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
  There are many thing about the boiware DB that me and Funky disagree on.  I don't think this is one of them.  With how many items you are going to end up storing in this DB and the fact that you are retriving them one at a time, You are going to create a lag monster with this script.   It is not really a matter of the size of the objects that you are storing.  It is more a matter of the number of times you are making calls to the DB. 

If you do want to continue to store items to the DB  by storing there object.  The best way to hadle that is to store them on a creature then store the creature into the DB with all the items on him.  this would allow you to store/retrive as many items as that creature can hold with just one call to the DB.  

With the system as you currently have it, only checking tags to see it the tiems are the same or not.  I would not worrie much about storing the objects for the items in the db.   There is no garentee that the items are the same from just a tag check.  Since there is no garentee I would change it to check the ResRef's of the items instead.  This would have the benifit of allowing you to store the resref's of the items instead of the objects themselves.   

With this option there are several way you can store the ResRef's into the DB all at once.   

Option 1 : would be to pack all the ResRef's into a single string and store it into the DB.  On retriving the string you would just need a function to split it back apart. 

Option 2; Store the ResRef's as local strings an on item.  Here again when you store the one item the whole merchant  is saved.  

option 3;  Make several DB items as per option 2 above. Perhaps one for each travaling merchant type.  Put all of the DB items into the inventory of a single creature.   Saving the Creature out to the DB will in effect save all the mini DB for the merchants as a single Master DB that can be loaded all at once by loading the creature.  

option 4: what ever else someone may think of. 

Just a few thought if you didnt mind storing the item as ResRef's instead of items.


 

#17
Greyfort

Greyfort
  • Members
  • 234 messages
I was trying to store item by resref, and the problem I run into is if a player customizes item by calling the resref the item looses its custumization, I think thats why they chose the store object. I my self am still trying to get the item props stored in db but there is no function that changes itemproperty(ip) to int etc so no way to store items properties, un less i make a file that makes the ip a int that can be stored. Of course i could have missed a function by not having a include...But I see no mention in the lexicon. anyone have a function that allows us to save itemproperties to NWN DB?

note:  I did find...
GetItemPropertyParam1
GetItemPropertyParam1Value

I might be able to use these to get property and property value if im undestanding them correctly.
the big issue now is making a table rather then one long string huh, we can make tables in the nwn DB right?

Modifié par Greyfort, 05 janvier 2011 - 05:00 .


#18
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Item properties are defined with 6 numbers (duration and such aside) - ip number, subtype, costtable, costtable value, paramater table, paramater value. Not all props use all of those - most don't need param table or value, and some are just type and subtype. You could probably work out a set of functions that just store ip type and subtype, but it wouldn't work for many properties.

Either way, if you're allowing customization of item properties, you probably want to store full objects. We store by resref on HG, and do allow customizations, but this involves storing a fairing complex encoding string for changes made to the item (we also store charges and identified status). Based on the difficulties you had above, I suspect that that would be a major struggle for you, and storing objects should cost you MUCH less development time.

I'll leave it up to you, though. This function shows how to get the base numbers from an item - it converts them into human readable format. The six relevant Get functions are in the second function, near the bottom. I had thought they were exclusive to nwnx_structs, but they don't appear to be:

/* WARNING: CAN BE VERY LAGGY */

string GetItemPropertyInfoDirect (int nType, int nSubType, int nCostTable, int nCostVal, int nParamTable, int nParamVal, int nCostChange=0) {
    string sRef, sRet = "";

    switch (nType) {
        case ITEM_PROPERTY_ABILITY_BONUS:
        case ITEM_PROPERTY_INVIS_ABILITY_BONUS:         sRet += (sRef = "Ability Bonus:");    break;
        case ITEM_PROPERTY_BONUS_SPELL_SLOT_OF_LEVEL_N: sRet += (sRef = "Spell Slot:");       break;
        case ITEM_PROPERTY_SAVING_THROW_BONUS:          sRet += (sRef = "Save Bonus:");       break;
        case ITEM_PROPERTY_SAVING_THROW_BONUS_SPECIFIC: sRet += (sRef = "Save Bonus:");       break;
        case ITEM_PROPERTY_WEIGHT_INCREASE:             sRet += (sRef = "Weight Increase:");  break;

        default: {
            sRef = Get2DAString("ITEMPROPDEF", "GameStrRef", nType);

            if (sRef != "" && sRef != "****")
                sRet += GetStringByStrRef(StringToInt(sRef));
        }
        break;
    }

    string sSubTable = Get2DAString("ITEMPROPDEF", "SubTypeResRef", nType);
    string sParamRow = Get2DAString("ITEMPROPDEF", "Param1ResRef", nType);

    if (sRef != "" && sRef != "****") {
        /* get param 1 override from subtype table if necessary */
        string sSubParamRow = Get2DAString(sSubTable, "Param1ResRef", nSubType);
        if (sSubParamRow != "" && sSubParamRow != "****")
            sParamRow = sSubParamRow;

        sRef = Get2DAString(sSubTable, "Name", nSubType);

        if (sRef != "" && sRef != "****")
            sRet += " " + GetStringByStrRef(StringToInt(sRef));
    }

    if (nCostTable > 0 && nCostTable < 255) {
        string sCostTable = Get2DAString("IPRP_COSTTABLE", "Name", nCostTable);
        sRef = Get2DAString(sCostTable, "Name", nCostVal);

        if (sRef != "" && sRef != "****") {
            sRef = GetStringByStrRef(StringToInt(sRef));

            if (GetStringLeft(sRef, 7) == "Resist " && GetStringRight(sRef, 4) == " / -")
                sRef = GetSubString(sRef, 7, GetStringLength(sRef) - 11) + "/-";

            sRet += " " + sRef;
        }

        if (nCostChange) {
            sRef = Get2DAString(sCostTable, "Name", nCostVal + nCostChange);

            if (sRef != "" && sRef != "****") {
                sRef = GetStringByStrRef(StringToInt(sRef));

                if (GetStringLeft(sRef, 7) == "Resist " && GetStringRight(sRef, 4) == " / -")
                    sRef = GetSubString(sRef, 7, GetStringLength(sRef) - 11) + "/-";

                sRet += " -> " + sRef;
            }
        }
    }

    if (sParamRow != "") {
        string sParamTable = Get2DAString("IPRP_PARAMTABLE", "TableResRef", StringToInt(sParamRow));
        sRef = Get2DAString(sParamTable, "Name", nParamVal);

        if (sRef != "" && sRef != "****")
            sRet += " " + GetStringByStrRef(StringToInt(sRef));
    }

    return sRet;
}

string GetItemPropertyInfo (itemproperty ip) {
    string sRet = GetItemPropertyInfoDirect(
        GetItemPropertyType(ip),
        GetItemPropertySubType(ip),
        GetItemPropertyCostTable(ip),
        GetItemPropertyCostTableValue(ip),
        GetItemPropertyParam1(ip),
        GetItemPropertyParam1Value(ip));

    if (GetItemPropertyDurationType(ip) == DURATION_TYPE_TEMPORARY)
        sRet += " [" + FloatToString(GetItemPropertyDurationRemaining(ip), 1, 2) + "s]";

    return sRet;
}

Funky

#19
Greyfort

Greyfort
  • Members
  • 234 messages
Thanks for that funky, I was going to ask about Item properties was struggleing with how to handle the props. loop through see if item prop matches 2da if true store to nwnDB, get item param etc,and then itempropery (ip) is not a int,float,string i see you found a way around that. I will give it a try.

I like your idea of: "We store by resref on HG, and do allow customizations, but this involves storing a fairing complex encoding string for changes made to the item (we also store charges and identified status) " I plan to store charges, stacksize, etc. I dont want it reseting like the object pw script. All though that will work for Birdman076, quickly if he needs it right away.

As far as development time, I dont mind the work good practice and therapy. I would realy like it to be done by resref and not object since there is that issue of overflow as Lightfoot described.
man hearing about HG makes me wish I had broadband instead of dial up so I could get your files and look at your wonderful server.

Modifié par Greyfort, 05 janvier 2011 - 07:52 .


#20
Greyfort

Greyfort
  • Members
  • 234 messages
GetItemPropertyDurationRemaining () this function can not be found perhaps this is the nwnx_structs that you talk about and thats a linux file or is there a windows version? I will pop over to nwnx and see...

I was not able to find anything on the nwnx web page about nwnx_structs

it calls for this funtion as fallows

//
//
string GetItemPropertyInfo (itemproperty ip);

string GetItemPropertyInfo (itemproperty ip) {
    string sRet = GetItemPropertyInfoDirect(
        GetItemPropertyType(ip),
        GetItemPropertySubType(ip),
        GetItemPropertyCostTable(ip),
        GetItemPropertyCostTableValue(ip),
        GetItemPropertyParam1(ip),
        GetItemPropertyParam1Value(ip));

    //if (GetItemPropertyDurationType(ip) == DURATION_TYPE_TEMPORARY)
    //    sRet += " [" + FloatToString(GetItemPropertyDurationRemaining(ip), 1, 2) + "s]";

    return sRet;
}

I excluded and got
hg_item_prop.nss(13): ERROR: CASE PARAMETER NOT A CONSTANT INTEGER
line 13         case ITEM_PROPERTY_INVIS_ABILITY_BONUS:         sRet += (sRef = "Ability Bonus:");    break;

I think I will just hold until your able to answer question about nwnx_structs
EDITED I found the answer you were right funky its a Linux module/plugin  for now i jus // the lines that were causing error, I will play with the GetItemPropertyInfo() function and see if i can get it to work with out the tempory duration issue

Modifié par Greyfort, 05 janvier 2011 - 10:11 .


#21
Greyfort

Greyfort
  • Members
  • 234 messages
//::////////////////////////////////////////////////////////////////////////////
//::
//:: pshop_onstorclo2
//::
//:: Idea , TritonX
//:: pshop_onstoreclose
//:: Script created by Old Man`s Beard, June 06
//:: Thanks to Lex and UOAbigail for their support
//
//:: put this script on the OnStoreClose Event of your merchant.
//:: The merchant`s waypoint shall not be placed in the module,
//:: the shop is created from the blueprint. In this script a database is created
//:: with the name of the merchant`s resref.
//::
//:: EDITED/ALTERED: Greyfort with Help from FunkySwerve
//::
//:: Created: 12.24.2010/01.06.2011
//::
//:: NOTE: script has dificulty clearing first item, first time store closed
//:: but if closed again it will clear first item if it matches second.
//:: In this case happens to be a dagger...
//::
//::////////////////////////////////////////////////////////////////////////////
// includes here //


//::///////////////////////
void main()
{

//////////////////////////
// default save data
object oStore = OBJECT_SELF;
string sDBName = GetTag(oStore);
object oItem;
int nNth = 0;

///////////////////////
// duplicat check
object oItmDupChk;
string sTag, sTag2;
int nDup=0;

//
if (GetIsObjectValid(oStore))
{
DestroyCampaignDatabase(sDBName);
oItmDupChk=GetFirstItemInInventory(oStore);
while (GetIsObjectValid(oItmDupChk))
{
nDup = ++nDup;
sTag=GetTag(oItmDupChk);
SetLocalString(oStore, "item_"+IntToString(nDup)+"", sTag);

oItmDupChk= GetNextItemInInventory(oStore);
}
SetLocalInt(oStore, "MaxNumItems", nDup);

oItem = GetFirstItemInInventory(oStore);
while (GetIsObjectValid(oItem))
{
nNth=++nNth;
sTag2=GetLocalString(oStore,"item_"+IntToString(nNth+1)+"");
// check for duplicate destroy them
if (sTag2 == GetTag(oItem))
{
SetLocalInt(oItem, "Destroyed", 1);
DestroyObject(oItem);
}
// stores item from chest2 to "trvl_merch" sDBName
if (!GetLocalInt(oItem, "Destroyed"))
{
StoreCampaignObject(sDBName,"ITEM_"+IntToString(nNth),oItem);
}
oItem = GetNextItemInInventory(oStore);
}
SetCampaignInt(sDBName,"N_ITEMS",nNth);
}
// now check local strings versus inventory


///////////////////
}//end of script

ok I'm sure my logics off again Huh funky, this is suposed to check the invy for duplicates and does but gets all but the first Item.  If anyone sees my error please let me know.

Also anyone Here if they have any windows mods/plugins that use the linux nwnx_strucs as descripbed in the post just above this one?

Modifié par Greyfort, 07 janvier 2011 - 07:28 .


#22
Birdman076

Birdman076
  • Members
  • 186 messages
If this is going to lag like crazy using the bioware DB perhaps it would be better just to go with the MySQL and I'll have to school myself up on that? Would it also be easier to script at that point?

#23
Greyfort

Greyfort
  • Members
  • 234 messages
well Birdman076 I have a working mod using nwn db, and fester pots scripts. if you send me a pm with yr email I will mail it to you. i will also put up a link here to the nwnvaults ware I will post it.

#24
Greyfort

Greyfort
  • Members
  • 234 messages
ok I have a issue with item properties im trying to make two functions, one gets the item property then Sets to nwnDB, the next gets the nwnDB data and then you can add item prop. I may just be very tired and should take a break. How do we acuretly save and retrive a item prop to the nwn db?

anyone have a working function for the nwndb I cant seem to take the function Fuzy gave me

string GetItemPropertyInfo (itemproperty ip) and turn it back to a working IP. i thought

itemproperty iProp=StringToInt("dbvar"); would work but it seems not to

#25
Greyfort

Greyfort
  • Members
  • 234 messages
here is my code:
//
//gets items properties sets to nwnDB
//
string SetDBItemProps(string sDBName,string sVarName,string sValue,object oObject);


string SetDBItemProps(string sDBName,string sVarName,string sValue,object oObject)
{
object oItem;
//Get the first itemproperty on the oItem
itemproperty ipLoop=GetFirstItemProperty(oItem);
int ntype;
int nSubType;
int nDurType;
string sValue;
//Loop for as long as the ipLoop variable is valid
while (GetIsItemPropertyValid(ipLoop))
{
int ntyp=GetItemPropertyType(ipLoop);
int nSubType=GetItemPropertySubType(ipLoop);
int nDurType=GetItemPropertyDurationType(ipLoop);
sValue=IntToString( ntype+"|"+ nSubType +"|"+ nDurType );
//Next itemproperty on the list...
ipLoop=GetNextItemProperty(oItem);
}

return sValue;
}

I'm going to get some rest Thanks for any input in advance

Modifié par Greyfort, 15 janvier 2011 - 03:04 .