Author Topic: DB object, and conversation help  (Read 321 times)

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
DB object, and conversation help
« on: September 21, 2011, 01:27:35 am »


               I can't see what I am doing wrong, any help is appreciated. 

  I want to track which NPCs the PC has spoken to on a database object so that I can have different conversation nodes appear on subsequent conversations.  These are the functions I wrote to do this

int Setdbobj(object oPC)
{
    object o = GetFirstItemInInventory(oPC);
    while(GetIsObjectValid(o))
    {
        if(GetTag(o) == "rl_travelerscoin") {
            SetLocalObject(oPC,"travelerscoin",o);
            SendMessageToPC(oPC,"DB object set");
            return 1;
        }
        o = GetNextItemInInventory(oPC);
    }
    SendMessageToPC(oPC,"DB object not set");
    return 0;
}
object Getdbobj(object oPC)
{
    return GetLocalObject(oPC,"travelerscoin");
}
void SetSpokenTo(object oPC)
{
    SetLocalInt(Getdbobj(oPC),GetLocalString(oPC,"conversing"),1);
}
int GetSpokenTo(object oPC)
{
    if( GetLocalInt(Getdbobj(oPC),GetLocalString(oPC,"conversing")) ) return TRUE;
        else return FALSE;
}
  I originally setup SetSpokenTo(object oPC, object oNPC) and GetSpokenTo(object oPC, object oNPC).  Then in the starting conditionals, I used GetPCSpeaker() and GetLastSpeaker() to figure out if the PC had spoken to them before, but GetLastSpeaker() doesn't seem to work.  I figured I could work around this by adding
SetLocalString(GetPCSpeaker(),"conversing",GetTag(OBJECT_SELF)); 
to the default OnConversation handle that all my NPCs use.  This way, I can get who the PC is speaking to in the conversation.

Starting conditionals:
/*if the PC has spoken to the NPC before, then do not show this node*/
int StartingConditional()
{
    if( GetSpokenTo(GetPCSpeaker()) ) return FALSE;
    else return TRUE;
}
/*if the PC has spoken to the NPC before, then show this node*/
int StartingConditional()
{
    return GetSpokenTo(GetPCSpeaker());
}
 
  If I have a conversation that starts with:
Hi, my name is Terrorble - using the 1st starting conditional
    Hi, nice to meet you. - I run a script using SetSpokenTo()
      ...conversation continues
Hi Mr PC, we've spoken before - using the 2nd starting conditional
  Yeah, how you been
    ...conversation continues

What happens is, the first NPC I speak to "seems" to work fine.  The 1st convo node appears, the 2nd doesn't.  Any NPC I speak to after that thinks I've already spoken to them.  When I add debug code, GetSpokenTo() will return TRUE, even if the tag of the NPC I'm speaking to, doesn't match the one it is checking on the DB object.  Meaning, I speak to Terrorble and it sets "Terrorble" with a value of 1 on the DB object.  Then I speak to the next guy, and the starting conditional checks the DB object to see if I've spoken to them.  It pulls up "Terrorble",1.  After I've spoken with the 2nd NPC and SetSpokenTo() has set that NPC's tag on the object, then when speaking to the 3rd NPC, the 2nd NPC's tag is returned from GetSpokenTo().

Sorry, that's sort of a mess to read.  If anyone wants to suggest an entirely different way to do this please do.
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
DB object, and conversation help
« Reply #1 on: September 21, 2011, 07:12:56 am »


               It really depends upon what you are setting this up for, for instance, if you are setting this up for a Server Module, then it's best to use a token, which is something the PC carries (and cannot drop), and just store variables on that, whenever you have finished setting the variable, optionally you can export the (single) character..  (Though this is a bad idea & usually not necessary, unless you check to see if the PC is polymorphed first, as polymorphed creatures get annoyed by the Export Character Function)

Basically you would want to store (whether on the token or in the database) a variable with the name of the NPC & then set the NODE # they are on, e.g. at each interval in the conversation, set that the PC has indeed read the line by settings the NODE that they are on, e.g., if on line 5, set it to NODE 5 (meaning they have read line 5, etc).

If the NPC has no node stored for the NPC, obviously they would NOT have talked to them before!  This way you can keep track of WHO they have talked to,and how far along they are in EACH & EVERY conversation...

However you decide to keep set/track variables is your call, for variables are, by all means, very complex & simple at the same time, they can store information in a wide array of ways, meaning you can use larger numbers to dictate which NPC they have talked to, like 1010 would mean they have talked to the first NPC and are on NODE 10 in that converation.. 2005, would mean they have talked to the 2nd NPC and are on NODE 5 in that conversation...  However that may not fit your system, so I just threw it out there to help you understand the power of variables & the various ways they can be used.

//This only works for Multi-Player modules!
object oToken = GetObjectPossessedBy(oPC, "tagname");
GetLocalInt(oToken, "NPCTAGNAME");

//This works for ANY Type of module..
GetCampaignInt("NPC_CONVERSATIONS", "NPCTAGNAME", oPC);

I would use Integers / strings / floats, not Objects...

Objects stored in the database usually have rather large amounts of information stored in the database, like what is in their inventory (if they have one) & all the variables on those items, age / sex/ race /etc /etc...

I hope that helped you some...
               
               

               


                     Modifié par _Guile, 21 septembre 2011 - 06:16 .
                     
                  


            

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
DB object, and conversation help
« Reply #2 on: September 21, 2011, 08:20:12 pm »


               

_Guile wrote...

//This only works for Multi-Player modules!
object oToken = GetObjectPossessedBy(oPC, "tagname");
GetLocalInt(oToken, "NPCTAGNAME");

//This works for ANY Type of module..
GetCampaignInt("NPC_CONVERSATIONS", "NPCTAGNAME", oPC);


So, why does the first option only work in multi-player mods?  And for my sake, what exactly constitutes a multi-player mod? (anything run via nwserver and joined over LAN or online; versus downloading a mod, clicking "Play", then "New", then "Other modules", and loading it for local play?)

I ask, because this may be a large part of my problem.

Thanks
               
               

               
            

Legacy_kalbaern

  • Hero Member
  • *****
  • Posts: 1531
  • Karma: +0/-0
DB object, and conversation help
« Reply #3 on: September 22, 2011, 01:08:11 am »


               If you use a DB Object (which I do in my own module) it just requires you play and test using a servervault character. The variables stored on an item only only work on a servervault character. So if your module is meant to use a servervault, everything is fine. You just can't do a quick test of anything relying on the DB Object (IE, using F9). You'll need to load the module with NWServer and select a vault PC.
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
DB object, and conversation help
« Reply #4 on: September 22, 2011, 02:17:22 am »


               LAN Server & Internet Server are technically both the same in respects to databases, as long as you are hosting it as a server, whether over the internet or on a LAN Game.  Playing an offline / single players game however will require you to store information directly into the database, instead of something on the PC.  

Storing information on an item on the PC is the best way to handle storing information, you can specifically store that object into the database or just save the character, and if you use both methods you have 2 copies!  Yay!  However, you must be using a module on a Server (whether LAN or Online), as variables set on the item/object are NOT Persistent in Single Player/Non-Server Games...
               
               

               


                     Modifié par _Guile, 22 septembre 2011 - 01:18 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
DB object, and conversation help
« Reply #5 on: September 22, 2011, 03:19:44 am »


               @Terrobie: I really have no Idea what Kalbaern and _guile are talking about.  

The problem in your script is that you are using the same local var name "conversing" in order to identify all of your NPC's.  So that reguardless of what NPC's you are talking to it is using the same var on your DBItem.   Your solution is to  have a unique ID varmane for each of the NPC"s.  If each NPC has a unique tag that would be the simplest to use.  You could append the Tag  to the "conversing"  var name something like this.  

void SetSpokenTo(object oPC)
{
   SetLocalInt(Getdbobj(oPC), "conversing"+GetTag(OBJECT_SELF), TRUE);
}

and
int GetSpokenTo(object oPC)
{
// since the Int we are retriving is already TRUE(1) or FLASE(0) we can just return it.  
return GetLocalInt(Getdbobj(oPC),"conversing"+GetTag(OBJECT_SELF));
}

For your starting conditions you can also get rid of the IF statments.  

Starting conditionals:
/*if the PC has spoken to the NPC before, then do not show this node*/
int StartingConditional()
{
    // Use a not (!) to return false if GetSpokneTo returns TRUE
   return !GetSpokenTo(GetPCSpeaker());
}
/*if the PC has spoken to the NPC before, then show this node*/
int StartingConditional()
{
   return GetSpokenTo(GetPCSpeaker());
}

If your NPC's do not have unique tags,but have unique names just replace the GetTag with GetName.
               
               

               
            

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
DB object, and conversation help
« Reply #6 on: September 24, 2011, 06:51:02 am »


               Thank you very much, Lightfoot.

The NPCs do have unique tags, and things are working nicely.

It's great to be able to move forward again.
               
               

               
            

Legacy_Morbane

  • Jr. Member
  • **
  • Posts: 79
  • Karma: +0/-0
DB object, and conversation help
« Reply #7 on: September 24, 2011, 08:09:43 am »


               Lightfoot is an enlightened modder - he helps every one he can. So ++rep Lightfoot - you da man