Aller au contenu

Photo

Multiplayer shifter bug


  • Veuillez vous connecter pour répondre
22 réponses à ce sujet

#1
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
I know this is an old issue, but a server I play on has recently been having problems with this again. A previous dev had fixed it for a while, but somehow the problem has partially returned (it is sporadic, sometimes is fine, and sometimes starts bugging out again.)

Specifically the bug in question is the on server save, causing a remorph, resulting in loss of merged stats (although the weapons getting permantely merged has also happend at least once recently.)

I found this on the Vault;
http://nwvault.ign.c....Detail&id=2450
but I am wondering if you all have any other suggestions?
Thanks, Laz

#2
Shadooow

Shadooow
  • Members
  • 4 470 messages
As stated there, I tried it and doesnt seen any effect. Most devs doesn't save (ExportSingleCharacter) a character if he is polymorphed. Didn't seen/heard better solution.


IDEA: It would be possible to fix this completely via total polymorph rewrite to use SetAppearance and with NWNX (funcs) but thats not easy. First it takes some time to script it second months to balance it...

#3
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thanks for the reply Shadow. So how do you set it up so the server dosen't save/export a PC that is polymorphed?

It's also quite odd that it happens inconsistantly. Sometime I get the server message in the combat logs "Your character was not saved because it was polymorphed, will try again later" when everything is working properly. But then when the bug occurs I get no message, and just the bug (loss of merged stats.) I think your right on too with it being related to exporting the PC because even when I am not experiencing the bug I can cause it to happen by manually exporting my character while shifted.

Modifié par Lazarus Magni, 08 avril 2011 - 07:21 .


#4
Shadooow

Shadooow
  • Members
  • 4 470 messages
Well by default NWN will not save a character. That must be some custom script in your module. The manual saving via Export Character button should be avoided, if players uses this as a way to save their character thats really bad, personally would disable it via NWNX because it allows exploits and then replaced by a save without export character but only when not polymorphed.

#5
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Well I don't know if it is a custom script or something in the server settings, but the servers do save the PC's every 5 or 10 min and everytime the player rests. The characters are on a shared server vault though (not local, and shared amoungst all the servers for the PW.) It does not export the saved character to the players vault, but sounds like it does to the server vault. There was a fix put in place for shifters which may have utalized part of Guillies (?) shifter system (although I can't seem to find that on the vault now), and it has been working fine for months, but just recently has been working only some of the time.

As I said when it is working, and the servers autosave the player gets a message in the combat log saying something to the effect "Character was not saved because it was polymorphed. Will try again soon." When it is not working however, which seems to happen sporadically, it looks like it is exporting the PC, and the bug occurs. I am not sure if I am really explaining it suficiently...

#6
Shadooow

Shadooow
  • Members
  • 4 470 messages
send your OnModuleLoad event script

#7
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
As ShaDoOoW Stated. The Game does not save the characters except for when they log off. So you may want to put a check there to see if they are shifted or not. I myself do not see a problem with players exporting there own character since they get saved to there local vault when they do it, and not to the server vault.

Any other saving of characters is going to be happening from custom scripts added to the module. You should go through them with a fine tooth comb.

As far as using any of Guillies's scripts. I would suggest going through them with a fine tooth comb. Or having someone look at the scripts before using them. Not all of his systems are the best scripting in the world.

#8
Shadooow

Shadooow
  • Members
  • 4 470 messages

Lightfoot8 wrote...

and not to the server vault.

They do.

Modifié par ShaDoOoW, 08 avril 2011 - 11:08 .


#9
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thanks again for the replies guys. As far as the onmodule load event script, I dont currently have access to it, although the host might give it to me if I asked.

As far as the manual export, that's not really the problem. Was just a way I could force the bug to happen. If I don't want that to happen I just won't export when polymorphed. The problem is it happening when I don't want it to (sporadically on server saves).

Light, your right, I suspect it is something with the custom scripts, or whatever derivation of Guillies our previous Dev used to try to fix it. Just not sure what to do about it since I am not much of a scripter myself.

Modifié par Lazarus Magni, 08 avril 2011 - 11:47 .


#10
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

ShaDoOoW wrote...

Lightfoot8 wrote...

and not to the server vault.

They do.


Well, I know that the export to the player vault, That is the way I have gotten copys of serveral of my characters that I have played on server vault servers.  As far as it also saving it to the server vault, I guess I have to say that I dont really know, I have never tested to see if it saved there also just assumed that it didn't

#11
the.gray.fox

the.gray.fox
  • Members
  • 127 messages
Hello.

Have a look at my Fox Spells package.
There is a script in it: fox_export_chars.
Its purpose is to export a player (or also all players).
If a player to export happens to be polymorphed, the script will ensure he retains all item properties.
The opening comment of the script explains its usage.

Hm. That script is practically stand-alone.
You may want to rip it and use it for your module -- no problem.
At best you have to delete a couple references to a constant I define elsewhere.
Nothing you can not handle on your own, I am sure.

-fox

Modifié par the.gray.fox, 09 avril 2011 - 04:04 .


#12
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thank you for the suggestion gray fox. Ever thought about a) uploading your spell system to the vault, and B) uploading that export script as a shifter bug fix to the vault?

#13
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
He has the system up loaded on this site.   The link is in his sig. 


Fox Spells

#14
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Yep I saw that I was just asking if Fox would consider uploading them to the Vault. I am sure many in the NWN community would be interested in both the spell system, and a shifter fix.

#15
the.gray.fox

the.gray.fox
  • Members
  • 127 messages
I thank you for the kind words, Lazarus.

And sorry for the delay. I am not very much active in internet. But eventually I creep around :-)

The reason I am not releasing my files on the vault is because they are not for everyone. Which is sad.
My project is essentially a framework (or "engine", big fad term everyone likes to speak) to do stuff with the spell system.
So you see, given the nature of Fox Spells, my scripts end up touching "delicate" spots of the game. Good knowledge (at times deep knowledge) of NWN is required to mod Fox Spells.

This is a scripters forums. Of all the users in here, few can effectively take on my project and mod it as they wish (we got two of them right here, I believe. But they are an exception, not the rule). All others will end up asking for help -- or even *much* help.

On top of that I am not the best writer of documentation (english is not even my first language).
I just am not gifted in that department. Although I have stuffed my code with comments, often the comments will not tell all the "fine prints" of the matter at hand. Comments can be no substitute for experience.

Now move all this onto the vault.
Of the large user base there... how many are modders and/or scripters to begin?
And, out of that group, how many are capable ones?

Haha -- Most of them (if not all) would be the same capable people from this very forum.
As far as I understand Fox Spells is already in the best fitting place, you see.
The link is accessible to anybody, and anybody is welcome to mod my project for their own needs.


-fox

#16
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
No need to apologize for the delay Gray, it's a videogame after all. Well it is your mod, so you do as you see fit. All I was saying is for people like me (non-scripters) it would be nice to have a working shifter fix on the vault, and if your file contains said fix, you would do me, and I am sure many others a favor by uploading it. In regards to you spell changes, it would just be a nice resource on the vault, you could post a disclaimer with it like: support (other than bug fixes) not included, mod at your own risk/ability, or something...

#17
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages

the.gray.fox wrote...

Hello.

Have a look at my Fox Spells package.
There is a script in it: fox_export_chars.
Its purpose is to export a player (or also all players).
If a player to export happens to be polymorphed, the script will ensure he retains all item properties.
The opening comment of the script explains its usage.

Hm. That script is practically stand-alone.
You may want to rip it and use it for your module -- no problem.
At best you have to delete a couple references to a constant I define elsewhere.
Nothing you can not handle on your own, I am sure.

-fox


I know your not big on providing advice for modifying your file, but I wonder if you or someone else could elaborate on this? I found the script and looked at it, but not sure which lines I should be deleting...
Thanks, Laz

#18
the.gray.fox

the.gray.fox
  • Members
  • 127 messages
You are welcome.
Here is a standalone version.

// +----------------------+
// | FOX_EXPORT_CHARS.nss |
// +----------------------+
//
// ExportAllCharacters()
// ExportSingleCharacter()
//
// [fox - 25 Apr 2011 - standalone version]
// This script is the solution to the problem of polymorphed PCs losing their
// precious itemproperties after an Export of their Character.
//
// This script is designed to run via ExecuteScript().
// Make it run for a PC for an ExportSingleCharacter().
// Make it run for anything else for an ExportAllCharacters().



// +-----------+
// | CONSTANTS |
// +-----------+
// Name of a LocalObject we set on a polymorphed PC prior to export him. We use
// this to keep, briefly, a reference to all his equipment.
const string sFox_EXPORT_SLOTn = "FOX_EXP_00";



// +------------+
// | PROTOTYPES |
// +------------+
void fox_ExportAllCharacters     ();
void fox_ExportSingleCharacter   (object oPC);
void fox_ReapplyEnhancements     (object oPC);
void fox_RemoveAllItemProperties (object oItem);
void fox_CopyAllItemProperties   (object oDest, object oSource);



void main ()
{
    /////////////////////////////
    // Who are we running for?

    object oSelf = OBJECT_SELF;

    // Is this a PC?
    if (GetIsPC (oSelf))
    {
        // He is. Attempt to export him alone.
        fox_ExportSingleCharacter (oSelf);
    }
    else
    {
        // Not a PC. We attempt to export every PC.
        fox_ExportAllCharacters ();
    }
}



// -----------------------------------------------------------------------------
// Only a helper function to reduce the clutter.
// Cycles through all PCs and export them all.
// -----------------------------------------------------------------------------
void fox_ExportAllCharacters ()
{
    ////////////////////////////
    // Cycle through all PCs.

    object oPC = GetFirstPC ();
    while (GetIsObjectValid (oPC))
    {
        fox_ExportSingleCharacter (oPC);

        oPC = GetNextPC ();
    }
}



// -----------------------------------------------------------------------------
// Only a helper function to reduce the clutter.
// Export the given PC.
// -----------------------------------------------------------------------------
void fox_ExportSingleCharacter (object oPC)
{
    // Check if this PC is polymorphed.
    int bPoly = FALSE;
    effect eSeek = GetFirstEffect (oPC);
    while (GetIsEffectValid (eSeek))
    {
        if (GetEffectType (eSeek) == EFFECT_TYPE_POLYMORPH)
        {
            bPoly = TRUE;
            break;
        }

        eSeek = GetNextEffect (oPC);
    }


    ////////////////////////////////////////////////////////////////////////////
    // If the PC is polymorphed, we create a temporary copy of his current
    // equipment. We set a LocalObject on him for each item we create a copy of.
    ////////////////////////////////////////////////////////////////////////////

    if (bPoly)
    {
        // Sanity check. Is the PC in a valid Area?
        if (!GetIsObjectValid (GetArea (oPC)))
        {
            ////////////////////////////////////////////////////////////////////
            // There is a period of time, during Area Transitions, in which the
            // PC is -technically- outside of the Area he was last in, and not
            // yet in the Area he is transitioning to. The length of this window
            // depends on the complexity of the Areas involved in the process.
            // It is possible that a script executes when the PC is in such a
            // no-Area, and any code involving Areas or Locations shall go bug.
            ////////////////////////////////////////////////////////////////////

            // PC is in a no-Area. Quit.
            return;
        }

        // Get the current location of this PC.
        location lAt = GetLocation (oPC);

        // Scan all equipped items on this polymorphed PC.
        int i;
        for (i = 0; i < NUM_INVENTORY_SLOTS; ++i)
        {
            object oEquip = GetItemInSlot (i, oPC);
            if (GetIsObjectValid (oEquip))
            {
                //////////////////////////////////////////////////////
                // Create, on ground, a copy of this equipped item.
                // -------------------------------------------------------
                // NOTE : The copy will stay around for a very brief time.
                //        Nobody will notice it.
                // -------------------------------------------------------

                object oCopy = CopyObject (oEquip, lAt, OBJECT_INVALID, "");
                if (GetIsObjectValid (oCopy))
                {
                    // Set a reference on the PC to the copy we have made.
                    SetLocalObject (oPC, sFox_EXPORT_SLOTn + IntToString (i), oCopy);
                }
            }
        }
    }


    /////////////////////
    // Export this PC.

    ExportSingleCharacter (oPC);


    /////////////////////////////////////////////////////////////////////////
    // If the PC is polymorphed, we now reinstate what itemproperties he just
    // lost to the export.
    /////////////////////////////////////////////////////////////////////////

    if (bPoly)
    {
        DelayCommand (0.1f, fox_ReapplyEnhancements (oPC));
    }
}



// -----------------------------------------------------------------------------
// This function takes care to reapply all the enhancements a polymorphed PC had
// at the time of the export of his Character.
// We discovered that, after an export, all equipped items but the Skin/Hide are
// re-spawned anew on the polymorphed PC. Thus we have a set of itemproperties
// that is missing. And there is no way to unequip nor equip items on a PC while
// polymorphed.
// Our solution is to create temporary copies of all items equipped pre-export.
// Then, post-export, we clear the equipped items on the polymorphed PC of all
// their itemproperties. And immediately after we reinstate all itemproperties
// from the copies we made pre-export. This is the only approach that can react
// properly to new properties added to the equipped items after a polymorph.
//
// Our logic is flawless :-)
// -----------------------------------------------------------------------------
void fox_ReapplyEnhancements (object oPC)
{
    // Scan all equipped items on this polymorphed PC.
    int i;
    for (i = 0; i < NUM_INVENTORY_SLOTS; ++i)
    {
        object oEquip = GetItemInSlot (i, oPC);
        if (GetIsObjectValid (oEquip))
        {
            string sKey = sFox_EXPORT_SLOTn + IntToString (i);

            // Get a reference to the temporary copy we made of this item.
            object oCopy = GetLocalObject (oPC, sKey);

            if (GetIsObjectValid (oCopy))
            {
                // Delete the reference (we no longer need it).
                DeleteLocalObject (oPC, sKey);

                // Remove all current itemproperties from the equipped item.
                fox_RemoveAllItemProperties (oEquip);

                // Copy all itemproperties from the temporary copy.
                // (the copy is destroyed within the function)
                DelayCommand (0.0f, fox_CopyAllItemProperties (oEquip, oCopy));
            }
        }
    }
}



// -----------------------------------------------------------------------------
// Only a helper function to reduce the clutter.
// Removes ALL itemproperties from the given item.
// -----------------------------------------------------------------------------
void fox_RemoveAllItemProperties (object oItem)
{
    itemproperty ipSeek = GetFirstItemProperty (oItem);
    while (GetIsItemPropertyValid (ipSeek))
    {
        RemoveItemProperty (oItem, ipSeek);

        ipSeek = GetNextItemProperty (oItem);
    }
}



// -----------------------------------------------------------------------------
// Only a helper function to reduce the clutter.
// Copy ALL itemproperties from the Source item to the Destination item.
// -----------------------------------------------------------------------------
void fox_CopyAllItemProperties (object oDest, object oSource)
{
    itemproperty ipSeek = GetFirstItemProperty (oSource);
    while (GetIsItemPropertyValid (ipSeek))
    {
        AddItemProperty (DURATION_TYPE_PERMANENT, ipSeek, oDest, 0.0f);

        ipSeek = GetNextItemProperty (oSource);
    }

    // Destroy the Source item.
    // (that is, the temporary copy item we made)
    DestroyObject (oSource, 0.0f);
}


-fox
  • KMdS! aime ceci

#19
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
That's fantastic Grey Fox, thank you so much! So this should work on it's own without any further editing?

Modifié par Lazarus Magni, 25 avril 2011 - 10:30 .


#20
the.gray.fox

the.gray.fox
  • Members
  • 127 messages

Lazarus Magni wrote...

That's fantastic Grey Fox, thank you so much! So this should work on it's own without any further editing?


Yes. It is a self-contained standalone script. Ready as-is.
To be run through ExecuteScript().
The Object you run it for dictates the work mode (ExportSingleCharacter() vs. ExportAllCharacters() ).
Run it for a Player to export that very Player alone.
Run it for any object other than a Player (example: the Module or a sword) to export all Players.

NOTE : This script is not to be used in conjunction with Fox Spells. First: it would not compile. Second: Fox Spells uses its own original and equivalent version of this one. So... keep the two things separate.

-fox



[edit]
Hm. By the way...

18 days ago ShaDoOoW wrote...

[...] The manual saving via Export Character button should be avoided, [...] because it allows exploits [...]


The exploit he refers to is the instant refill of HP and THP in case the Player polymorphed to a creature who received Temporary Hit Points. Most polymorph shapes do this.

Said exploit is easily defeated. Zero away the THP bonus defined in polymorph.2da.
Then have your polymorph script take care to apply said THP bonus using EffectTemporaryHitpoints().
Doing so the export process shall not refill HP nor THP -- so defeating any malicious use of manual exports.

There would be more to tell about polymorphs, but I would go off topic.
If you want to learn all details, have a look at my polymorph system within Fox Spells.

-fox

Modifié par the.gray.fox, 26 avril 2011 - 01:52 .


#21
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Hmm, thanks again for the reply Grey Fox. Problem is that the server autosaves every 5 min or so, and that's when the bug happens. Will that script fire automatically on it's own when this occurs?

#22
Terrorble

Terrorble
  • Members
  • 194 messages
The auto-save feature for your server *likely* fires from your module's OnHeartbeat script. (Look at the events tab under module properties) If you look in that script, there's a good chance you'll find where it is exporting the characters every 5min. Comment out that line and add one like this in its place: ExecuteScript("fox_export_chars", GetModule());
*This assumes the file name for fox's function is fox_export_chars

I think that would cover it.

btw Fox, thanks for this, I'll be working this into the server I play since we suffer from a similar issue.

Modifié par Terrorble, 27 avril 2011 - 02:20 .


#23
Lazarus Magni

Lazarus Magni
  • Members
  • 1 134 messages
Thank you for the advice Terrorble. Guile also gave me the link to his shifter system that has a similar script in it as well (I think.)
http://nwvault.ign.c...=198735&id=3773
That is what we used to fix this most recently I believe. I have forwarded this info to the server host, and hopefully he will try one or both of these solutions out soon.
Thanks for all the help everyone.
Laz