Author Topic: Need Help with Custom Include  (Read 580 times)

Legacy_Genisys

  • Hero Member
  • *****
  • Posts: 961
  • Karma: +0/-0
Need Help with Custom Include
« on: August 11, 2010, 11:14:27 pm »


               This is the include which I'm going to be using in a Custom Binding Rod, which allows for Recall Back to saved locations, however, I having problems with the NWN database, and I don't have a part for NWNX2, therefore, I'm asking a talented scripter to help me here...

Can someone who is skilled in database scripting help me make this include correct and add NWNX2 functionality to it as well?

Your help will be greatly apprecated, not just by me, but by the community as well, for this script is going in my custom scripted items module which I'm making for the community. (It's going to be HUGE!)

Here is what I have so far in the include script... (Edited 8/13/10) - Tested To Be Good (Offline or Online)

////////////////////////////////////////////////////////////////////////////
//Script Name:  gen_bind_inc    (Include Script)
///////////////////////////////////////////////////////////////////////////
//Created By: Genisys (Guile)
//Created On: 7/25/10
///////////////////////////////////////////////////////////////////////////
/*
  Set the important settings below for the Binding Rod System!
  This system uses database, but it doesn't have to!
*/
///////////////////////////////////////////////////////////////////////////

//Set this to FALSE if you DON'T want to use a Database
//NOTE: By use of Database the system IS PERSISTENT! (BUT Not For Recall!)

const int USE_DATABASE = TRUE; //Default = TRUE ~ Use The NWN Database

//Set this to 1 for Storing by Account Login Name (Not The Character's Name)
//Set this to 2 for storing by Public CD Key
//Set this to 3 for storing by the Genisys ID Token System (Must have my Current Starter Module!)

const int  USE_THIS_ID_SYSTEM = 1; //Default = 1 (Use PC Login Name)

//Set this to 1 if you if this is a Multiplayer Online Module
//Set this to 2 if this is a Single Player Module!
//Set this to 3 only if you have my (Genisys / Guile) most recent starter modules

const int MODULE_BINDING = 2; //Default = 2 (Single Player Offline Modules)

///////////////////////////////////////////////////////////////////////////////
//Declare Custom Prototypes
string BINDING_NAME(object oPC);
location GetCampLoc(object oPC, int nSlot);
void SetTokenLocation(location lSaved, int nSaved);
void SetTokens(object oPC);
void SetBindedLocation(object oPC, location lStored, int nSlot);

//////////////////////////////////////////////////////////////////////////////
//Define Custom Prototypes

//////////////////////////////////////////////////////////////////////////////
string BINDING_NAME(object oPC)
{

  string sBind = "BINDING_LOCATION"; //Default String..

  object oToken = GetItemPossessedBy(oPC, "id_token");
  string sToken = GetName(oToken);

  string sAdd;
  int nMod;

  if(MODULE_BINDING == 1)
  {
   nMod = TRUE;
  }
  else if(MODULE_BINDING == 2)
  { nMod = FALSE; }
  else if(MODULE_BINDING == 3)
  {
   nMod = GetLocalInt(GetModule(), "MULTI");
  }

 //If we are using the Database System..
 if(USE_DATABASE)
 {
   //In Multi Player we use the Player's Login Account Name
  if(USE_THIS_ID_SYSTEM == 1)
  {
    //Limit to 18 Characters...
    sAdd = GetStringLeft(GetPCPlayerName(oPC), 18);
  }
  //In Single Player we use the Player's CD Key Only...
  else if(USE_THIS_ID_SYSTEM == 2)
  {
    sAdd = GetPCPublicCDKey(oPC, nMod);
  }
  //For the Unique Player ID System (Works offline or online!) IN MY MODULES ONLY
  else if(USE_THIS_ID_SYSTEM == 3)
  {
    sAdd = sToken;
  }
   //Send this as what to use...
   return sBind + sAdd;
 }
 //Otherwise we are NOT Using the Database System, so do this instead..
 else
 {
  //In Multi Player we use the Player's Login Account Name
  if(USE_THIS_ID_SYSTEM == 1)
  {
    //This needs to be something else...
    sAdd = GetStringLeft(GetPCPlayerName(oPC), 24);
  }
  //In Single Player we use the Player's CD Key Only...
  else if(USE_THIS_ID_SYSTEM == 2)
  {
    sAdd = GetPCPublicCDKey(oPC, nMod);
  }
  //For the Unique Player ID System (Works offline or online!) IN MY MODULES ONLY
  else if(USE_THIS_ID_SYSTEM == 3)
  {
    sAdd = sToken;
  }
   //Tell the script to use this instead for - Non-Database Storing..
   return sBind + sAdd;
 }

//Function End
}

///////////////////////////////////////////////////////////////////////////////
location GetCampLoc(object oPC, int nSlot)
{
 string sCamp = "GEN_BINDINGS";
 string sVar;
 location lVar;
 //If we are using the Database
 if(USE_DATABASE)
 {
  sVar = BINDING_NAME(oPC);
  return GetCampaignLocation(sCamp, sVar, oPC);
 }
 else
 {
  sVar = "BINDING_LOCATION";
  return GetLocalLocation(oPC, sVar);
 }

 return lVar;

//Function End
}

////////////////////////////////////////////////////////////////////////////////
void SetTokenLocation(location lSaved, int nSaved)
{
  object oArea;
  int nToken = 420 + nSaved; //eg 421, 422, 423 etc..
  string sName;

  oArea = GetAreaFromLocation(lSaved);
  if(oArea != OBJECT_INVALID)
  {
   sName = GetName(oArea);
  }
  else
  {
    sName = "Location Not Stored";
  }

  SetCustomToken(nToken, sName);

//Function End
}

///////////////////////////////////////////////////////////////////////////////
void SetTokens(object oPC)
{

  string sID = BINDING_NAME(oPC);
  location l1,l2,l3,l4,l5,l6;

  if(USE_DATABASE)
  {
   //NOTE: This will function properly for any module, because it validates area!
   l1 = GetCampaignLocation("GEN_BINDINGS", sID + "1", oPC);
   l2 = GetCampaignLocation("GEN_BINDINGS", sID + "2", oPC);
   l3 = GetCampaignLocation("GEN_BINDINGS", sID + "3", oPC);
   l4 = GetCampaignLocation("GEN_BINDINGS", sID + "4", oPC);
   l5 = GetCampaignLocation("GEN_BINDINGS", sID + "5", oPC);
   l6 = GetCampaignLocation("GEN_BINDINGS", sID + "6", oPC);
  }
  else
  {
   l1 = GetLocalLocation(oPC, sID + "1");
   l2 = GetLocalLocation(oPC, sID + "2");
   l3 = GetLocalLocation(oPC, sID + "3");
   l4 = GetLocalLocation(oPC, sID + "4");
   l5 = GetLocalLocation(oPC, sID + "5");
   l6 = GetLocalLocation(oPC, sID + "6");
  }

  SetTokenLocation(l1, 1);
  DelayCommand(0.1, SetTokenLocation(l2, 2));
  DelayCommand(0.2, SetTokenLocation(l3, 3));
  DelayCommand(0.3, SetTokenLocation(l4, 4));
  DelayCommand(0.4, SetTokenLocation(l5, 5));
  DelayCommand(0.5, SetTokenLocation(l6, 6));

//Function End
}

///////////////////////////////////////////////////////////////////////////////
void SetBindedLocation(object oPC, location lStored, int nSlot)
{

 string sBind = BINDING_NAME(oPC);
 string sSlot = IntToString(nSlot);
 location lVar;

 SetCampaignLocation("GEN_BINDINGS", sBind + sSlot, lStored, oPC);

//Function End
}

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

I'm using the functions above in scripts which are part of a conversation..
               
               

               


                     Modifié par Genisys, 13 août 2010 - 04:54 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Need Help with Custom Include
« Reply #1 on: August 12, 2010, 04:52:07 am »


                int nMod = FALSE; //Default = FALSE (It's Single Player Module)
...
//In Single Player we use the Player's CD Key Only...
  else if(USE_THIS_ID_SYSTEM == 2)
  {
    sAdd = GetPCPublicCDKey(oPC, nMod);
  }
...

Looks to me like nMod is always going to be false for a single player game. 


// Get the public part of the CD Key that oPlayer used when logging in.
// - nSinglePlayerCDKey: If set to
TRUE, the player's public CD Key will
//   be returned when the player is playing in single player mode
//   (otherwise returns an empty string in single player mode).

string GetPCPublicCDKey(object oPlayer, int nSinglePlayerCDKey=FALSE)
               
               

               


                     Modifié par Lightfoot8, 12 août 2010 - 03:54 .
                     
                  


            

Legacy_Melkior_King

  • Full Member
  • ***
  • Posts: 234
  • Karma: +0/-0
Need Help with Custom Include
« Reply #2 on: August 12, 2010, 07:01:58 am »


               Speaking personally, I wouldn't use a database.

I'd make sure that every area in my module had a unique tag, then extract the area tag, x,y,z and facing from the location and store those in the item description (probably at the end) just after a unique "marker" string, using SetDescription.

To get the location back, use GetDescription and FindSubString to locate the unique marker string then extract the area tag, position and facing and use them to build a new location variable which points to the stored location.  If the location is to be use-once, you can then use a new SetDescription to erase the stored location.

The only caveat here is what I mentioned above: Make sure every area in your module has a unique tag.  If two or more areas have the same tag, the script won't be able to tell them apart and will always send the player to the first area it finds with that tag.

If done right, this method will persist across resets and be faster than using a database.
               
               

               


                     Modifié par Melkior_King, 12 août 2010 - 06:04 .
                     
                  


            

Legacy_Genisys

  • Hero Member
  • *****
  • Posts: 961
  • Karma: +0/-0
Need Help with Custom Include
« Reply #3 on: August 12, 2010, 02:42:06 pm »


               Thanks for catching that gross error lightfoot8, I appreciate that...

Is your method persistent for single player modules as well Melkior_King?

If so, do you have the script functions to help me on that one?
I hate doing GetString functions, they give me a headache, too much thinking...

The problem I see is players logging out, or crashing, then comming back without any binded locations.
I like your idea Melkior, it has a lot of merit.
               
               

               


                     Modifié par Genisys, 12 août 2010 - 01:42 .