Author Topic: RE: Sending a PC to a Stored Location After Server Reset - FAIL  (Read 551 times)

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« on: January 27, 2013, 11:13:01 pm »


                Help....
I've got this weird issue with returning characters to their previous location when they reenter the server.
I store the character's location into the campaign database in the OnClientLeave event. Then in the OnClientEnter hook I check if the db has a stored location for that player and if it does I jump them to that location. Everything works fine as long as I don't restart the server. 
When I restart the server the jump never occurs even though the location is still stored. I thought the player's public cd-key remained the same so I'm sure what the issue is...
I have done some digging and came up with an alternate - storing the location on a player database item. Works great as long as I do not restart the server. Do I need to export the character in the OnClientLeave event to get these variables to stick around after a server reset or is the problem with the stored location?
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #1 on: January 27, 2013, 11:17:27 pm »


               The solution is to store the location in its constituent parts. BUT instead of storing the area as an object, store it as the area's tag. The position vector can be stored as a float for each piece of it X, Y, Z and rotation.

In NBDE Knat does just this when storing a location to the database.
               
               

               
            

Legacy_virusman

  • Sr. Member
  • ****
  • Posts: 448
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #2 on: January 27, 2013, 11:17:52 pm »


               Player's location is automatically stored by the server without any scripting. External database is necessary to save/restore player's location across restarts. So probably your script is just not working. Check if it saves anything at all.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #3 on: January 27, 2013, 11:26:54 pm »


               Virusman, he's talking about this being a problem across server resets.

The problem is that the game object for the area can change across restarts. And thus the Location data is not good after a restart.

The way around this is to come up with a better way to store the area. This will allow you to have the correct area when you recreate the location from its parts when you need it.

[edit] Thanks for posting this, BTW, it reminded me of this problem. I need to adjust my contribution t this month's CCC.
               
               

               


                     Modifié par henesua, 27 janvier 2013 - 11:30 .
                     
                  


            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #4 on: January 27, 2013, 11:29:57 pm »


               We use this script to save the PC's location, and it works fine through a server reset. An external database is not needed.


void main()
{
    object oPC = GetPCSpeaker();
    object oArea = GetArea(oPC);
    string sPCName = GetName(oPC);  // Gets the name of the PC
    string CDKey = GetPCPublicCDKey(oPC); // Gets the public CD Key of the player . . . adds to quality of check
    string sID = GetStringLeft(sPCName,10); // Indivudual Character Used
    string sHID = sID+CDKey; // HCR Style;
    string sAreaName = GetName(oArea);  // Sets up a string using the name of the Area
    string sAreaTag = GetTag(oArea); // Sets up a string using the Tag of the Area
    if(GetIsPC(oPC)||(GetIsDM(oPC) && !GetIsDMPossessed(oPC)))  // Script will fire for PCs and DMs
    {
        vector vPosition = GetPositionFromLocation(GetLocation(oPC));
        float nX = vPosition.x;
        float nY = vPosition.y;
        float nZ = vPosition.z;
        int nAreaX = FloatToInt(nX);
        int nAreaY = FloatToInt(nY);
        int nAreaZ = FloatToInt(nZ);
        string sAreaX = IntToString(nAreaX);
        string sAreaY = IntToString(nAreaY);
        string sAreaZ = IntToString(nAreaZ);
        // Set an Int so we can check for a saved location in the portal or trigger
        SetCampaignInt("PlayerStartLoc", "StartLocSet_" + sHID, 1, oPC);
        // Create Persistent Location Data
        SetCampaignInt("PlayerStartLoc", "AreaX_" + sHID, nAreaX, oPC);
        SetCampaignInt("PlayerStartLoc", "AreaY_" + sHID, nAreaY, oPC);
        SetCampaignInt("PlayerStartLoc", "AreaZ_" + sHID, nAreaZ, oPC);
        SetCampaignString("PlayerStartLoc", "AreaTag_"+ sHID, sAreaTag, oPC);
        // Tell the player what the Saved Area will be for verification
        SendMessageToPC(oPC, "Persistent Saved Location is " + sAreaName);
        // Apply a visual effect.
        effect eVFX;
        eVFX = EffectVisualEffect(VFX_FNF_STRIKE_HOLY);
        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVFX, GetLocation(oPC));
    }
}
               
               

               


                     Modifié par Sadira of Tyr, 27 janvier 2013 - 11:32 .
                     
                  


            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #5 on: January 27, 2013, 11:46:10 pm »


               Wow, Sadira that saves me a ton of work. Thanks '<img'> Now how to I get him back there when the server restarts and the Player enters?
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #6 on: January 27, 2013, 11:59:49 pm »


               You are welcome. Here is our port back script, used with an area trigger.

// This script pulls data for location and jumps PC to last save point
// Use this in the onused event of a portal or onenter of a trigger or a conversation
void main()
{
    // uncomment the proper definition of the player object for your use!!!
    object oPC = GetEnteringObject();
    //object oPC = GetLastUsedBy();
    //ojbect oPC = GetLastSpeaker();
    if(GetIsPC(oPC)||(GetIsDM(oPC) && !GetIsDMPossessed(oPC)))  // Script will fire for PCs and DMs
    {
    string sPCName = GetName(oPC);  // Gets the name of the PC
    string CDKey = GetPCPublicCDKey(oPC); // Gets the public CD Key of the player . . . adds to quality of check
    string sID = GetStringLeft(sPCName,10); // Indivudual Character Used
    string sHID = sID+CDKey; // HCR Style user check
    // Read Persistent Location Data
    int nPlayerBeenHere = GetCampaignInt("PlayerStartLoc", "StartLocSet_" + sHID, oPC);  // The check to see if PC has a saved location
    int nAreaX = GetCampaignInt("PlayerStartLoc", "AreaX_" + sHID, oPC);
    int nAreaY = GetCampaignInt("PlayerStartLoc", "AreaY_" + sHID, oPC);
    int nAreaZ = GetCampaignInt("PlayerStartLoc", "AreaZ_" + sHID, oPC);
    string sAreaName = GetCampaignString("PlayerStartLoc", "AreaName_" + sHID, oPC);
    string sAreaTag = GetCampaignString("PlayerStartLoc", "AreaTag_"+ sHID, oPC);
    // Set up the location from Database info
    float y = IntToFloat(nAreaY);
    float x = IntToFloat(nAreaX);
    float z = IntToFloat(nAreaZ);
    vector vTargetLoc = Vector(x, y, z);
    location lTargetLoc = Location(GetArea(GetObjectByTag(sAreaTag)), vTargetLoc, 0.0);
    if(nPlayerBeenHere == 1) // if the player has a saved location lets run this scripts
        {
            if (GetCurrentHitPoints(oPC)<=0)  // See if the PC has 0 or less HPs . . . added this for HCR death system
            {
            SendMessageToPC(oPC,"You are still be dead...");
            }
            else // If the PC is above 0 HPs, send them to their last save location
            {
            SendMessageToPC(oPC,"Portaling to your Saved Location in 3 Seconds...");
            DelayCommand(3.0, AssignCommand(oPC, ActionJumpToLocation(lTargetLoc)));
            }
        }
    }
}
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #7 on: January 28, 2013, 12:09:38 am »


               I have to run so I will make this fast.

I see no need to break the entire location down for storage. The only problem with the stored location is the area, and that is only if the module was worked on and the area order changes.

Simply storing the location and the area tag should be good enough to rebuild a valid location.

location lLoc = Get**Location();
string sArea = Get**AreaTag();
lLoc = location (GetObjectByTag(sArea), GetpositionFromLocation(lLoc), GetFacingFromLocation(lLoc));

May be errors above, Just typing from memory to give an Idea.

As far as the problem you are having, I would have to check and see if the location in the OnClientLeave event is valid. You may need to store the location before that event fires. After all does not the Area Exit Event fire first? Once the pC leaves the area there location is no longer valid.
               
               

               


                     Modifié par Lightfoot8, 28 janvier 2013 - 12:11 .
                     
                  


            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #8 on: January 28, 2013, 12:48:56 am »


               Lightfoot, this sounds more promising. I couldn't get Sadira's scripts to work correctly - probably caused by my implementing them through OnClientLeave and the OnClientEnter hook script (x3_mod_pre_enter).

Tried moving the store location script to Area OnExit and still no go. It appears that nothing is being stored in the database for the area, making me certain that the area or location is no long valid even from that event.
               
               

               


                     Modifié par Pstemarie, 28 janvier 2013 - 01:30 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #9 on: January 28, 2013, 01:29:55 am »


                this is how i do it in my spell focus system - storing a location on an item


location GetSpellFocusLocation(object oFocus)
{


   return  Location(   GetObjectByTag(GetLocalString(oFocus, SPELLFOCUS_LOCATION_TAG)),
                       Vector( GetLocalFloat(oFocus, SPELLFOCUS_LOCATION_X),
                               GetLocalFloat(oFocus, SPELLFOCUS_LOCATION_Y),
                               GetLocalFloat(oFocus, SPELLFOCUS_LOCATION_Z)
                             ),
                       GetLocalFloat(oFocus, SPELLFOCUS_LOCATION_F)
                   );
}

// Stores a location on a spell focus. - [FILE: spellfocus_inc]
void StoreSpellFocusLocation(object oFocus, location lLoc)
{
   vector vPos     = GetPositionFromLocation(lLoc);

   SetLocalString(oFocus, SPELLFOCUS_LOCATION_TAG, GetTag(GetAreaFromLocation(lLoc)));
   SetLocalFloat(oFocus, SPELLFOCUS_LOCATION_X, vPos.x);
   SetLocalFloat(oFocus, SPELLFOCUS_LOCATION_Y, vPos.y);
   SetLocalFloat(oFocus, SPELLFOCUS_LOCATION_Z, vPos.z);
   SetLocalFloat(oFocus, SPELLFOCUS_LOCATION_F, GetFacingFromLocation(lLoc));
}
               
               

               
            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #10 on: January 28, 2013, 01:53:47 am »


               Ok here's what I'm basically looking for -

1. The PW is a LAN PW and although I could leave my computer on all the time I really don't want to pay the higher electricity bill to do so - besides we only play once every other week or so.

2. The Server must be able to be reset (see above)

3. Therefore, I want to be able to store a PCs location when they leave the module and I want this to be persistent across resets.

4. I'd like to avoid using a trigger or conversation to do so. I just want the player to be able to exit and when they do the game stores their location in the database.

5. I'm using bioware's database because NWNX is so far over my head I feel like Lurch whenever I look at it.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #11 on: January 28, 2013, 02:09:19 am »


               

Pstemarie wrote...
I want to be able to store a PCs location when they leave the module and I want this to be persistent across resets.


I store this on module heartbeat and it works for me. Module Heartbeat typically runs between 4 and 6 times a minute as far as I can tell. I'll post my code on pastebin.

Pstemarie wrote...
I'm using bioware's database because NWNX is so far over my head I feel like Lurch whenever I look at it.


Bio DB is adequate. But I recommend using Knat's NBDE to increase its speed. I fixed a few functions in it which you should have access to now.
               
               

               


                     Modifié par henesua, 28 janvier 2013 - 04:31 .
                     
                  


            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #12 on: January 28, 2013, 02:15:26 am »


               Knat's NDBE doesn't exactly play nicely with the systems I've got in place - Alternate Horse Scripts and Killer Death System.
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #13 on: January 28, 2013, 02:17:39 am »


               I am sure I can make it work for you just fine if you are willing to let me help. Let me know.

Otherwise, I can write a non-NBDE system for this if you would like. In fact... the one I posted above could easily be adapted.
               
               

               
            

Legacy_Pstemarie

  • Hero Member
  • *****
  • Posts: 4368
  • Karma: +0/-0
RE: Sending a PC to a Stored Location After Server Reset - FAIL
« Reply #14 on: January 28, 2013, 02:29:35 am »


               Don't get me wrong - I need the help badly. I plan on looking into NBDE again. I just haven't gotten to it. Your previous post gave me some ideas so I'm going to try those, but please post your code cause I'm skeptical my idea will work.