Database integration

How about some scripting tutorials regarding database integration
Using the Bioware Data base is easier than most might think. If you understand how to "Set" and "Get" Local variables then you are more than half way there. For example, Setting a Local variable on a PC you might use something like this SetLocalInt( oPC, "VARIABLE_NAME", 1). Storing this variable in the Database is just as simple. The only difference is you must provide a Campaign (or database) name. I.e. SetCampaignInt( "DATABASE_NAME", "VARIABLE_NAME", 1, oPC) Notice the object the variable is assigned to is now listed last. Also note that this object is not necessary, however I highly recommend it because without it, variables can easily be over written. The ability to assign variables to specific PCs also make the database much more useful in that fact that a single data base can hold a lot of information about each PC, without the need to create separate DBs for each PC. Take this script for example, when the PC joins the game, it will record each stat of each PC â€“ all in one DB.

// Place in OnClientEnter // Will store each ability score as: // ABILITY_0 = STRENGTH // ABILITY_1 = DEXTERITY // ABILITY_2 = CONSTITUTION // ABILITY_3 = INTELLIGENCE // ABILITY_4 = WISDOM // ABILITY_5 = CHARISMA void main {   object oPC = GetEnteringObject; if(!GetIsPC(oPC)) return; int i,iAb; for(i=0; i<6; i++) {       iAb = GetAbilityScore(oPC,i); SetCampaignInt("STATS","ABILITY_"+IntToString(i),iAb,oPC); } }

Since each score is assigned to the entering PC, the next PC wonâ€™t over-write the previously stored values. When the first PC enters, the database basically will look like this;

ABILITY_0 ___ JassperJassper Krane ___ 17 ABILITY_1 ___ JassperJassper Krane ___ 29 ABILITY_2 ___ JassperJassper Krane ___ 16 ABILITY_3 ___ JassperJassper Krane ___ 16 ABILITY_4 ___ JassperJassper Krane ___ 10 ABILITY_5 ___ JassperJassper Krane ___ 14

Note the "JassperJassper Krane", this is the Player ID that is set when the variable is assign to a PC object. This uses the players Login name plus the character name.

Side note: Any time you use one of the SetCampaign* Functions, if the specified database does not yet exist, it will automaticaly be created.

So what happens to the database when a second PC logs in? It will look something like this

ABILITY_0 ___ JassperJassper Krane ___ 17 ABILITY_1 ___ JassperJassper Krane ___ 29 ABILITY_2 ___ JassperJassper Krane ___ 16 ABILITY_3 ___ JassperJassper Krane ___ 16 ABILITY_4 ___ JassperJassper Krane ___ 10 ABILITY_5 ___ JassperJassper Krane ___ 14 ABILITY_0 ___ JassperJade Krane ___ 17 ABILITY_1 ___ JassperJade Krane ___ 30 ABILITY_2 ___ JassperJade Krane ___ 17 ABILITY_3 ___ JassperJade Krane ___ 17 ABILITY_4 ___ JassperJade Krane ___ 11 ABILITY_5 ___ JassperJade Krane ___ 15

Notice that the original data is still there, along with the new Player stats and it is all within the same database. When a PC logs in for the second time, and that PCs stats have already been recorded, then those values will be over written with that PCs current values, so any changes would be recorded.

Side note: You can use a DBF viewer such as DBFNavigator http://www.alxsoft.narod.ru/ENG/dbfnav.htm (free Download) to view your database outside of the game. This enables you to study what is actually recorded.

Now if you needed to check a ability value, lets say INTELLIGENCE you use the GetCampaignInt function, which works a lot like the GetLocalInt function. We simply need to specify what database to draw from, like this GetCampaignInt( "STATS", "ABILITY_3", oPC); If oPC is the "JassperJade Krane" player object, then the result returned would be 17.

Obviously, the example above has no real value as it would be much less CPU intensive to simply call GetAbilityScore when ever a ability score is needed rather than store them in a DB and retrieve them later, but it is important to know what assigning the variables to Player objects do. I feel that this is one of the most misunderstood aspects of the Bioware Database and I have seen many "assume" that they must create a new DB for each PC as well as each Variable, this is not the case.

Now lets create something somewhat useful. Here is a Scenario, Lets say I have 5 quest and each quest has different "levels" of completion. I want to record what level of completion each PC is on for each quest and restore those values when they enter the module. This will keep track of their quest progress even after a server reset. During Game play I will set local variables on the PC and the in the database, this way I donâ€™t need to access the DB each time I need to check the status of a quest. Because during a conversation, I will most likely check the value many times more often, and only need to set the values once.

For example, My PC starts some of the quest via some conversations, in one of the ActionTaken scripts I would set the values with something like this,

void main {   object oPC = GetPCSpeaker; SetLocalInt(oPC,"QUEST_1",3); SetCampaignInt("QUEST_STATUS","QUEST_1",3,oPC); }

This will set the completion level of quest 1 to 3 on my PC and in the DB. Later in a different conversation I can simply check what level the PC is on in a quest by a Starting Conditional script something like this;

int StartingConditional {   if(GetLocalInt(GetPCSpeaker,"QUEST_1") == 3) {       return TRUE; }   return FALSE; }

Side Note: Why not use the OnClientLeave node to record all the variables? Because the OnClientLeave script fires only after the PC logs out, therefore there is no valid PC object to relate the variables too. The Player ID, as seen above, would be blank. There are ways around that issue, but that isnâ€™t the scope of this subject.

So lets say I played long enough to get to the 3rd part of quest 1, didnâ€™t start quest 2, 2nd part of quest 3, didnâ€™t start quest 4, and completed quest 5. I want to restore these numbers when that PC logs back in after a server reset so My OnClientEnter script would look something like this,

void main {   object oPC = GetEnteringObject; if(!GetIsPC(oPC))return; int i,iQuest; for(i=1; i<6; i++) {       iQuest = GetCampaignInt("QUEST_STATUS","QUEST_"+IntToString(i),oPC); SetLocalInt(oPC,"QUEST_"+IntToString(i),iQuest); } }

This will retrieve the variables from the DB and set them back onto my PC. Now all the quest states are restored on the PC and all my convo scripts can still check the quest status using GetLocalInt. What happens when a PC logs in that doesnâ€™t have any records in the Database? Nothing really, all the QUEST_* variables will be set to 0 on that PC, which is what they are by default.

Message me if this info was helpful or if you need further clarification. If so I will continue with other DB functions.