Author Topic: Troublesome stores  (Read 1203 times)

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Troublesome stores
« Reply #15 on: January 03, 2011, 08:33:53 am »


                 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.


 
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #16 on: January 05, 2011, 03:49:14 am »


               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 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Troublesome stores
« Reply #17 on: January 05, 2011, 05:31:30 am »


               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
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #18 on: January 05, 2011, 07:50:15 am »


               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 .
                     
                  


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #19 on: January 05, 2011, 07:58:42 am »


               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 .
                     
                  


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #20 on: January 07, 2011, 07:25:55 am »


               //::////////////////////////////////////////////////////////////////////////////
//::
//:: 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 .
                     
                  


            

Legacy_Birdman076

  • Sr. Member
  • ****
  • Posts: 320
  • Karma: +0/-0
Troublesome stores
« Reply #21 on: January 07, 2011, 01:32:39 pm »


               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?
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #22 on: January 10, 2011, 11:11:39 pm »


               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.
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #23 on: January 14, 2011, 02:59:42 am »


               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
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #24 on: January 14, 2011, 03:13:11 am »


               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 .
                     
                  


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #25 on: January 15, 2011, 03:10:02 am »


               Another issue is taking the stored string and turning it into a item prop as seen in this code:

int nMaxIndex= GetCampaignInt(sDBName,"NumItems",oObject);
int nIndex;
for (nIndex = 1; nIndex
{
sItmCreate=GetCampaignString(sDBName,"Item_"+IntToString( nIndex )+"",oObject);
object oItem=CreateObject(OBJECT_TYPE_ITEM,sItmCreate,GetLocation(OBJECT_SELF) );
   if( !GetIsObjectValid (oItem) )
   {
       int nMaxIndexProp= GetCampaignInt(sDBName,"Item_"+IntToString( nIndex )+"_MaxItemProps",oObject);
       int nIndexProp;
       for (nIndexProp = 1; nIndexProp
       {
       itemproperty ipProperty;
       string ipString= GetCampaignString(sDBName,"Item_"+IntToString( nIndex )+"_ItemProp_"+IntToString( nIndexProp )+"",oObject );
       ipProperty = StringToInt( ipString );
       AddItemProperty(DURATION_TYPE_PERMANENT,ipProperty,oItem);
       }//end of for item props
   }//end of if oItem valid
}//end of for number of items

ipProperty = StringToInt( ipString ); as seen in this line I get...ERROR: MISMATCHED TYPES
yet a Item property is a int when whe use StringToInt(Get2DAString(string s2DA, string sColumn, int nRow);

so I'm perplexed by the error.  And on the aboved script trying to make a function, i see I was trying to make string tokens and forgot to code that right. man i was tired yesterday when I posted it.
               
               

               


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


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #26 on: January 15, 2011, 04:51:02 am »


               I was wandering If any know of the top of there head will what I have written here work correctly for the  GetStringTokenizer(string sString, string sDelim) function?  I'm trying to get the property of a item broken up and stored in nwnDB

//
//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;

string sDelimiter = "|";
string sType;
string sSubType;
string sDurType;
//Loop for as long as the ipLoop variable is valid
while (GetIsItemPropertyValid(ipLoop))
  {
    ntype=GetItemPropertyType(ipLoop);
    sType=IntToString(ntype);

    nSubType=GetItemPropertySubType(ipLoop);
    sSubType=IntToString(nSubType);

    nDurType=GetItemPropertyDurationType(ipLoop);
    sDurType=IntToString(nDurType);

  //sValue=IntToString( ntype+"|"+ nSubType +"|"+ nDurType );
  sValue= sType+ sDelimiter + sSubType + sDelimiter + sDurType;
  //Next itemproperty on the list...
  ipLoop=GetNextItemProperty(oItem);
  }

return sValue;
}
               
               

               


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


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Troublesome stores
« Reply #27 on: January 15, 2011, 05:48:32 am »


               If you are talking about the X0_I0_STRINGLIB function I dont see why it would not work.   Even though I use that include way to much, it is not that effecient.  I also normally only use the GetTokenByPosition function.  Using the other functions in the include can make it a little more effecient, But not by enough for me to go through the headach of using them. 

If you want an already written more efficent way to parse the string, I would sugest looking at

string StringParse(string sSource, string sDelimiter = " ", int bRightToLeft = FALSE)
and
string StringRemoveParsed(string sSource, string sParsed, string sDelimiter = " ", int bRightToLeft = FALSE)

From the 'x3_inc_string' include file.
               
               

               
            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
Troublesome stores
« Reply #28 on: January 16, 2011, 10:42:18 pm »


               ok once again, the issue I seem to have is when I get a item property and store it in the nwnDB as a string, and then retrive the string from the nwnDB I get...



       itemproperty ipProperty;

       string ipString= GetCampaignString(sDBName,"Item_"+IntToString( nIndex )+"_ItemProp_"+IntToString( nIndexProp )+"",oObject );

       ipProperty = StringToInt( ipString );// error this line



itm_exam_get.nss(67): ERROR: MISMATCHED TYPES



Its my understanding that I need to store the Item props as strings then turn them into int but I keep getting error
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Troublesome stores
« Reply #29 on: January 17, 2011, 03:11:36 am »


               I think you are going the wrong way with this.  Yes you can tare the Iprop apart and rebuild it.  The reason you are getting you error is that  an itemproptery is not an 'int'  it is a structure of type itempoperty.  so you will have to rebuild it mor along the lines shown below.



#include "x0_i0_stringlib"

 void main()
{
  object oItem;
  // to turn the iproptery into a string.
  itemproperty  ipProperty =  GetFirstItemProperty (oItem);
  string sIprop = IntToString (GetItemPropertyType(ipProperty));
  sIprop +=       "|"+IntToString(GetItemPropertyCostTableValue(ipProperty));
  sIprop +=       "|"+ IntToString(GetItemPropertyDurationType (ipProperty));
  sIprop +=       "|"+ IntToString( GetItemPropertyParam1(ipProperty));
  sIprop +=       "|"+ IntToString( GetItemPropertyParam1Value(ipProperty));
  sIprop +=       "|"+ IntToString( GetItemPropertySubType(ipProperty));

  // To turn the string  back to an Iproperty is going to be harder.
  int nPropType= StringToInt( GetTokenByPosition(sIprop,"|",0));
  int nPropValue=StringToInt( GetTokenByPosition(sIprop,"|",1));
  int nDuration =StringToInt( GetTokenByPosition(sIprop,"|",2));
  int nPram1    =StringToInt( GetTokenByPosition(sIprop,"|",3));
  int nPram1Val =StringToInt( GetTokenByPosition(sIprop,"|",4));
  int nSubType  =StringToInt( GetTokenByPosition(sIprop,"|",5));

  object oNewItem;
  itemproperty ipRemadeProp;
  switch (nPropType)
  {
     case ITEM_PROPERTY_ABILITY_BONUS:
       ipRemadeProp= ItemPropertyAbilityBonus( nSubType, nPropValue);
       break;
     case ITEM_PROPERTY_AC_BONUS:
       ipRemadeProp = ItemPropertyACBonus( nPropValue);
       break;
     /// ect. making a case for each of the 48 or so item properties.
  }

  // add the prop to the item.
  AddItemProperty( nDuration ,ipRemadeProp,oNewItem);
}

I think you would be much better served writing a rutine to store all the items on an NPC. or more then one NPC depending on the number of items.  Along with a function to compare if items are the same or not. 

I once wrote such a function,  It however died with the hard drive i had it stored on.  I just have not gotten around to writting it again yet. 

Best of luck in what ever direction you decide to go,
L8