Author Topic: Can anyone point me to a script or utility that removes/merges items from players on log in?  (Read 2194 times)

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               Can anyone point me to a script or utility that removes items from players on log in if they are either: a) no longer in the mod, or 'B)' merges them to conform to what is currently in the mod?
               
               

               
            

Legacy__Knightmare_

  • Full Member
  • ***
  • Posts: 191
  • Karma: +0/-0


               I'm not sure exactly what you are asking for here. I'm not sure A is possible (if understood correctly). The player has left the module so there is no PC object that you can have an affect on. For B, no idea what you mean.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               I don't mean the player is no longer logged on, I mean if a logged in player has an item that is no longer in the module.

To answer your question about b, I mean say an item was originally incorporated (uploaded) into a module. Later it was determined to be overpowered, or whatever, and the existing version changed to something more reasonable. Is there a way to check on player log in. that their items get changed to what is currently in use?

Basically this is for a PW that is over 8 years old. It has had, as you might imagine, numerous generations of builders, Devs, and players. Some of the content from previous generations is not in alignment with that is currently perceived as "balanced" (*ducks and covers after throwing the B word out...*) So either we can let everything in as is, or wipe everybodys items (which I would also be curious if anyone could point me to some resource for doing this to a player vault items, while leaving their characters and exp in tack, as a back up contingency plan), or handle it on a case by case basis (which would be possible, but hoping some scripting option might save me a TON of work.)
               
               

               


                     Modifié par Lazarus Magni, 16 juin 2011 - 04:56 .
                     
                  


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0


               Hmm that can be an issue:
1) items that are no longer in the mod:  You would need some sort info on all current items to check against...
2) merges to conform to mod: this is dependant on above to make compareisons and then destroy old and give new that is closest to old.

both these require going through pc invy and equiped items, and compareing each item to a list.
then setting var on item that doesn't conform for destruction, then giving item thats equal or close to old one this becomes little harder be cause you are comparing item props.

I would recomend:
If possible have players meet with DM and adjustments made that way.

Other wise strip all gear invy and equiped, getting gold value of each and giveing player gold
so they can equip them selfs.  Players may not like it but it solves issue of players haveing that +20 vorpal, time stopping sword '<img'>
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               

Greyfort wrote...

Other wise strip all gear invy and equiped, getting gold value of each and giveing player gold
so they can equip them selfs. Players may not like it but it solves issue of players haveing that +20 vorpal, time stopping sword '<img'>


So can you point me to a script of utility that does this? The alternative is, starting with a fresh vault, returning vets requesting characters restored, and then on restoring them loading first as a DM and going through their inv. A big old headache when your talking a guild of 2000+... Hell even 20+ when considering some players have 20+ toons...
               
               

               


                     Modifié par Lazarus Magni, 16 juin 2011 - 05:08 .
                     
                  


            

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0


               I could write something for you that loops thru all the player's items, destroys them, and  gives them a new version of each.  This way, everything they have would match the current blueprints for every item in the mod.  If I'm not mistaken, if  you try to create a new version for an item that no longer exists at all, then it simply would not be created - which solves any issues of removed items being in the mod.

This is based on one important assumption:  when you "balanced" an item, you editted the original  version in the palette, rather than creating a new version with a different blueprint resref to replace it.  The script would look at the resref of the item, then create that same item on the player after destroying the old one.  If an item with a different resref is replacing an item, then everything is considerably harder.

I'm not near the toolset and won't be for a few days if you don't mind waiting.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               If there is no such thing already available, and you have the time and desire to create such a script that would certainly be fantastic Terroble. I am guessing having a script fire like this every time a player logs in would probably be rather resource intensive for a server. If it could be made so that an aDMin could run it on a player on an individual basis (like when saids players first get imported into the mod), or to run on the entire server vault a single time, that would probably be preferable.

BTW your assumption is correct for the most part, certain items have been changed over time, but their resref's have not. The ones that have different resrefs could easily be handled on there own I believe.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0


               If I'm understanding this correctly you could use something like this for a DM wand/widget. Tag based script. It would loop through all inventory items, all bags in inventory, and all equipped items:

void ResRefMatchReplace(object oItem, object oTarget)
{
    string sResRef = GetResRef(oItem);
    if (sResRef == "blah blah blah1")
    {
        DestroyObject(oItem);
        CreateItemOnObject("res ref of replace item", oTarget);
    }
    if (sResRef == "blah blah blah2")
    {
        DestroyObject(oItem);
        CreateItemOnObject("res ref of replace item", oTarget);
    }
    //etc...
}

void TagMatchReplace(object oItem, object oTarget)
{
    string sTag = GetTag(oItem);
    if (sTag == "blah blah blah1")
    {
        DestroyObject(oItem);
        CreateItemOnObject("res ref of replace item", oTarget);
    }
    if (sTag == "blah blah blah2")
    {
        DestroyObject(oItem);
        CreateItemOnObject("res ref of replace item", oTarget);
    }
    //etc...
}

#include "x2_inc_switches"
void main()
{
    int iEvent = GetUserDefinedItemEventNumber();
    if (iEvent != X2_ITEM_EVENT_ACTIVATE) return;
    object oActivator = GetItemActivator();
    if (!GetIsDM(oActivator)) return;

    object oTarget = GetItemActivatedTarget();
    object oItem = GetFirstItemInInventory(oTarget);
    int iSlot;

    //Get items in inventory and replace if needed
    while (GetIsObjectValid(oItem))
    {
        //if item is a container, loop through items inside
        if (GetHasInventory(oItem))
        {
            object oConItem = GetFirstItemInInventory(oItem);
            while (GetIsObjectValid(oConItem))
            {
                ResRefMatchReplace(oConItem, oTarget);
                //TagMatchReplace(oConItem, oTarget);
                oConItem = GetNextItemInInventory(oItem);
            }
        }
        else
        {
            ResRefMatchReplace(oItem, oTarget);
            //TagMatchReplace(oItem, oTarget);
        }
        oItem = GetNextItemInInventory(oTarget);
    }

    //Get equipped items and replace if necessary
    for (iSlot=0; iSlot<NUM_INVENTORY_SLOTS; iSlot++)
    {
        oItem = GetItemInSlot(iSlot, oTarget);
        if (GetIsObjectValid(oItem))
        {
            ResRefMatchReplace(oItem, oTarget);
            //TagMatchReplace(oItem, oTarget);
        }
    }
}


This is more of a template. You would need to fill in all the tags or resrefs that you need to in the 2 functions above the main sript. Hope it helps. Good luck.
               
               

               


                     Modifié par GhostOfGod, 16 juin 2011 - 08:37 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               Thank you for the Template Ghost. Is there a simple way to extract the item tags, and resrefs in a Mod though? The mod literally has 1000s of items... Looking each up individually would be nearly a life long endevor...
               
               

               


                     Modifié par Lazarus Magni, 16 juin 2011 - 08:48 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0


               We have an item updater script that does this. When an item's resref is changed, a Version variable is incremented on it, and an entry added into a script. If you haven't been keeping track of changes, you would have to replace everything on the first go-round (tagging pcs that have been updated somehow, via persistent variable or other means), and then start versioning. I can share the code if you like, but it uses nwnx for hashsets.

Funky
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0


               

Lazarus Magni wrote...

Thank you for the Template Ghost. Is there a simple way to extract the item tags, and resrefs in a Mod though? The mod literally has 1000s of items... Looking each up individually would be nearly a life long endevor...


So you have 1000s of items that changed? Or you don't know the tags/res refs that changed? Are you wanting to replace every item the player has? I'm a bit confused.

In those first 2 functions you don't list every item. Just the items that changed that you want to replace with some other item. And you don't have to use both functions. You can just use one if you want. I just left it open so that you could use tags or res refs of the changed items.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               The problem is basically threefold. There are 1000's of items, I don't know all of which ones has been changed (although I do know some), and some players have overpowered items in their vault (on their characters or in their item vault) that are not in the mod (either given by previous DMs, or were removed from the mod a while ago.) Does that make sense?

So if I am understanding correctly, the script you wrote Ghost, will work for any items that I know the resrefs and tags for that I want to replace? But there would still be the problem for the unknown items... Is that right?
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0


               Yes, that sums up the problem accurately, with Ghost's script or any other. This is why I indicated the need for an initial all-items scan. Additionally, if you're using object-based banking, rather than resref-based, you would need to scan/replace all the vaults as well. That's possible, but quite a pain. The alternative, a vault wipe, is a very bad idea, as far as player retention goes.

Here's our item updater code. It fires on client enter, and automatically waits until the player hits the first area of the mod where they spend any amount of time, freezing them in place if the need for any updates is detected:

[code=auto:0]
#include "hg_inc"

#include "ac_itemreq_inc"
#include "ac_copycraft_inc"

#include "fky_chat_inc"
#include "inc_draw"

#include "hg_antidupe_inc"
#include "x2_inc_itemprop"

void ArtifactExplode (object oPC) {
    int i;
    object oItem;
    location lCenter = GetLocation(oPC);
    effect eImpact, eDamage, eLink;

    for (i = 0; i < NUM_INVENTORY_SLOTS; i++) {
        oItem = GetItemInSlot(i, oPC);

        if (GetLocalInt(oItem, "Artifact")) {
            WriteTimestampedLogEntry("ARTIFACT EXPLOSION : " + GetPCPlayerName(oPC) + " : " + GetName(oPC) + " : " + GetName(oItem));
            SetItemStackSize(oItem, 1);
            SetPlotFlag(oItem, FALSE);
            DestroyObject(oItem);
        }
    }

    oItem = GetFirstItemInInventory(oPC);

    while (GetIsObjectValid(oItem)) {
        if (GetLocalInt(oItem, "Artifact")) {
            WriteTimestampedLogEntry("ARTIFACT EXPLOSION : " + GetPCPlayerName(oPC) + " : " + GetName(oPC) + " : " + GetName(oItem));
            SetItemStackSize(oItem, 1);
            SetPlotFlag(oItem, FALSE);
            DestroyObject(oItem);
        }

        oItem = GetNextItemInInventory(oPC);
    }

    ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SCREEN_SHAKE), lCenter);
    DelayCommand(0.25, DrawSphere(1, 249, lCenter, 0.25, 0.0, 30, 0.0, 0.0, 0.0, "z"));
    DelayCommand(2.75, DrawSpiral(0, 76, lCenter, 0.0, 23.0, 0.0, 60, 13.0, 0.7, 0.0, "z"));
    DelayCommand(2.75, DrawSpiral(0, 469, lCenter, 0.0, 23.0, 0.0, 60, 13.0, 0.7, 0.0, "z"));
    DelayCommand(3.00, DrawCircle(0, 22, lCenter, 5.0, 0.0, 10, 1.0, 0.0, 0.0, "z"));
    DelayCommand(3.50, DrawCircle(0, 22, lCenter, 11.0, 0.0, 13, 1.0, 0.0, 0.0, "z"));
}

void DestroyOriginalItem (object oItem) {
    SetPlotFlag(oItem, FALSE);
    DestroyObject(oItem);
}


void ReplaceItem (object oTarget, object oItem, string sRes) {
    string sName = GetName(oItem);

    string sLog = "UPDATEITEMS : " + GetName(oTarget) + " (" +
        GetPCPlayerName(oTarget) + ") : " + sName + " (" +
        GetResRef(oItem) + ") [v" + IntToString(GetLocalInt(oItem, "Version")) + "] -> ";

    int nCharges = GetItemCharges(oItem);
    string sUniqueID = GetLocalString(oItem, "UNIQUE_ID");

    if (GetLocalInt(oItem, "Artifact") || GetLocalInt(oItem, "Singleton"))
        SetLocalInt(oItem, "NoCopyCrafting", 1);

    DeleteLocalInt(oItem, "Artifact");
    DeleteLocalInt(oItem, "Singleton");
    DeleteLocalString(oItem, "UNIQUE_ID");

    int nBaseType = GetBaseItemType(oItem);

    if (sRes == GetResRef(oItem)                    &&
        !GetLocalInt(oItem, "NoCopyCrafting")       &&
        (nBaseType == BASE_ITEM_ARMOR               ||
         nBaseType == BASE_ITEM_HELMET              ||
         GetItemIsShield(oItem)                     ||
         GetItemIsWeapon(oItem))) {

        AssignCommand(GetModule(), DelayCommand(0.0, DestroyOriginalItem(oItem)));

        object oCopy = CreateItemOnObject(sRes, oTarget, 1);

        if (!GetLocalInt(oCopy, "Artifact")  &&
            !GetLocalInt(oCopy, "Singleton") &&
            !GetLocalInt(oCopy, "NoCopyCrafting")) {
            AssignCommand(GetModule(), DelayCommand(0.0, DestroyOriginalItem(oCopy)));

            oCopy = CopyItemCrafting(oItem, oCopy);
        }

        SetPlotFlag(oItem, FALSE);
        SetLocalInt(oItem, "REPLACED", 1);
        DestroyObject(oItem);

        oItem = oCopy;
    } else if (nBaseType == BASE_ITEM_RING && sRes == "multi_signet") {
        int i, j;

        AssignCommand(GetModule(), DelayCommand(0.0, DestroyOriginalItem(oItem)));

        SetPlotFlag(oItem, FALSE);
        SetLocalInt(oItem, "REPLACED", 1);

        object oRing = CreateItemOnObject(sRes, oTarget, 1);

        /* copy the charges from the last Ring of the Planar Traveler */
        if (GetResRef(oRing) == GetResRef(oItem)) {
            SetLocalInt(oRing, "Charges_", 10);
            SetLocalInt(oRing, "Charges_100", 10);

            for (i = 1; i <= 4; i++) {
                for (j = 1; j <= 9; j++)
                    SetLocalInt(oRing, "Charges_" + IntToString((100 * i) + 10 + j), 10);
            }
        }

        DestroyObject(oItem);

        oItem    = oRing;
        nCharges = 0;
    } else {
        if (nBaseType == BASE_ITEM_MAGICWAND && sRes == "wandoftime" && GetLocalInt(oItem, "Version") < 3 && nCharges <= 5) {
            if ((nCharges = nCharges * 5) > 50)
                nCharges = 50;
        }

        AssignCommand(GetModule(), DelayCommand(0.0, DestroyOriginalItem(oItem)));

        SetPlotFlag(oItem, FALSE);
        SetLocalInt(oItem, "REPLACED", 1);
        DestroyObject(oItem);

        if (GetStringLeft(sRes, 1) == "#") {
            GiveGoldToCreature(oTarget, StringToInt(GetSubString(sRes, 1, 10)));
            sRes  = "DESTROY";
            oItem = OBJECT_INVALID;
        } else
            oItem = CreateItemOnObject(sRes, oTarget, 1);
    }

    if (GetIsObjectValid(oItem)) {
        WriteTimestampedLogEntry(sLog + GetName(oItem) + " (" + sRes + ") [v" +
            IntToString(GetLocalInt(oItem, "Version")) + "] : REPLACED" +
            (GetItemPossessor(oItem) != oTarget ? " AND DROPPED" : ""));

        if (nCharges > 0 && GetItemCharges(oItem) > 0 && !GetLocalInt(oItem, "NoRecharge"))
            SetItemCharges(oItem, nCharges);

        if (sUniqueID != "")
            SetLocalString(oItem, "UNIQUE_ID", sUniqueID);

        SetIdentified(oItem, TRUE);
    } else if (sRes == "DESTROY")
        WriteTimestampedLogEntry(sLog + sRes + " : DESTROYED");
    else
        WriteTimestampedLogEntry(sLog + sRes + " : FAILED");

    if (sRes != "DESTROY" && sRes != "drowdust") {
        FloatingTextStringOnCreature("Your " + sName + " has been replaced with a new version.", oTarget, FALSE);

        if (GetIsObjectValid(oItem) && GetItemPossessor(oItem) != oTarget)
            FloatingTextStringOnCreature(COLOR_RED + "Your new " + sName +
                " is on the ground. Please pick it up.</c>", oTarget, FALSE);
    }
}


string GetItemUpdate (object oItem) {
    if (!GetIsObjectValid(oItem))
        return "";

    int nVersion = GetLocalInt(oItem, "Version");
    int nBaseType = GetBaseItemType(oItem);
    string sRes = GetStringLowerCase(GetResRef(oItem));
    string sTag = GetStringLowerCase(GetTag(oItem));


    DeleteLocalInt(oItem, "ZEP_CR_TEMPITEM");

    /* destroy already-replaced items */
    if (GetLocalInt(oItem, "REPLACED"))
        return "DESTROY";

    /* destroy old pet givers */
    if (GetStringLeft(sRes, 10) == "custompet0")
        return "DESTROY";

    /* destroy guild points on relog */
    if (sRes == "newguildpoint" && GetTag(GetArea(GetItemPossessor(oItem))) == "DocksofAscension")
        return "DESTROY";

    /* integrate and destroy guild tokens */
    if (GetStringLeft(sTag, 5) == "guild" && GetStringRight(sTag, 5) == "token") {
        int nGuild;
        string sGuild = GetSubString(sTag, 5, 1);
        object oPC = GetItemPossessor(oItem);

        if (sGuild == "g")
            nGuild = GetLocalInt(oItem, "Guild");
        else
            nGuild = StringToInt(sGuild);

        if (nGuild == GUILD_ETERNAL_ORDER_MERGED_WITH_REDS)
            nGuild = GUILD_ETERNAL_REDS;

        SetLocalInt(oPC, "Guild", nGuild);
        SetPersistentInt(oPC, "Guild", nGuild);

        return "DESTROY";
    }

    /* replace old ammo containers */
    if (GetStringLeft(sRes, 3) == "uaq" || GetStringLeft(sRes, 13) == "quiverofendle") {
        if (sTag != "ac_rng_uacont")
            return sRes;
    }

    /* replace +6 AC mystic weapons with new versions */
    if (GetItemIsMeleeWeapon(oItem)           &&
        GetStringLeft(sRes, 9) == "scorching" &&
        GetItemACValue(oItem) > 0) {

        return sRes;
    }

    /* replace old CEP tridents */
    if (nBaseType == 300)
        return sRes;

    /* replace buggy CEP appearances on armor */
    if (nBaseType == BASE_ITEM_ARMOR &&
        GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO) == 175) {

        SetLocalInt(oItem, "NoCopyCrafting", 1);
        return sRes;
    }

    /* replace old PC Scry tools */
    if (sTag == "pclist" && !GetLocalInt(oItem, "New"))
        return sRes;

    /* set FKY_CHAT_INSTANT on PC Scry, Command Targeter, and DM Voice Thrower */
    if (!GetLocalInt(oItem, "FKY_CHAT_INSTANT") &&
        (sRes == "pclist"          ||
         sRes == "autocaster"      ||
         sRes == "fky_chat_target" ||
         sRes == "fky_chat_ventril")) {

        if (sRes == "autocaster") {
            IPRemoveAllItemProperties(oItem, DURATION_TYPE_PERMANENT);

            /* add 'Talk To' and 'Unique Power Self Only' in that order */
            AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyCastSpell(536, 13), oItem);
            AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyCastSpell(335, 13), oItem);

            SetLocalString(oItem, "FKY_CHAT_INSTANT_SCRIPT", "ev_autocaster");
        }

        SetLocalInt(oItem, "FKY_CHAT_INSTANT", 1);
    }

    /* set Artifact local on artifacts that don't have it */
    if (sTag == "ssith5sstadisben" ||
        sTag == "rtyglegendaryhor" ||
        sTag == "theeyeofvecna") {

        SetLocalInt(oItem, "Artifact", 1);
    }

    /* return old honed weapons to normal */
    if (sTag == "assasswpncrit")
        return sRes;

    /* integrate the old Greater Dragon Breath with RDDs */
    if (sTag == "rddbreath") {
        object oRDD = GetItemPossessor(oItem);
        int nRDDLevel = GetLocalInt(oItem, "RDD_Level");

        SetLocalInt(oRDD, "RDDLevel", nRDDLevel);
        SetPersistentInt(oRDD, "RDDLevel", nRDDLevel);

        if (GetPersistentInt(oRDD, "RDDLevel") == nRDDLevel)
            return "DESTROY";
    }

    /* ensure all unlimited heal packs require the Beaker */
    if (sRes == "unlimitedhealpac")
        SetLocalString(oItem, "UnlimitedSourceTag", "bountifulbeaker");


    object oMod = GetModule();

    /* replace items that swap to new resrefs */
    string sNew = HashSetGetLocalString(oMod, "UpdateItemRes", sRes);
    if (sNew != "")
        return sNew;

    /* replace items with new versions */
    int nVer = HashSetGetLocalInt(oMod, "UpdateItemVer", sRes);
    if (nVer > GetLocalInt(oItem, "Version"))
        return sRes;

    if (HashSetGetLocalInt(oMod, "UpdateItemSingleton", sRes) && !GetLocalInt(oItem, "Singleton"))
        return sRes;

    if (HashSetGetLocalInt(oMod, "UpdateItemUndroppable", sRes) && GetItemCursedFlag(oItem)) {
        itemproperty ip;

        for (ip = GetFirstItemProperty(oItem);
             GetIsItemPropertyValid(ip);
             ip = GetNextItemProperty(oItem)) {

            if (GetItemPropertyType(ip) == ITEM_PROPERTY_INVIS_ADDITIONAL &&
                GetItemPropertyCostTableValue(ip) == IP_CONST_ADDITIONAL_UNDROPPABLE)
                break;
        }

        if (!GetIsItemPropertyValid(ip)) {
            ip = ItemPropertyInvisAdditional(IP_CONST_ADDITIONAL_UNDROPPABLE);
            AddItemProperty(DURATION_TYPE_PERMANENT, ip, oItem);
        }
    }

    /* fix broken random weapons with monster damage */
    if (GetStringLeft(sRes, 6) == "randwp" && GetItemHasItemProperty(oItem, ITEM_PROPERTY_MONSTER_DAMAGE))
        return sRes;

    /* update charges on the Ring of the Planar Traveler */
    if (sTag == "multi_signet") {
        string sServer = GetLocalString(oMod, "ServerNumber");

        if (sServer != "")
            SetItemCharges(oItem, 1 + (GetLocalInt(oItem, "Charges_" + sServer) * 2));
    }

    if (sTag == "hellskull" && !GetItemHasItemProperty(oItem, ITEM_PROPERTY_CAST_SPELL)) {
        itemproperty ip = ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY,
                                                IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE);

        AddItemProperty(DURATION_TYPE_PERMANENT, ip, oItem);
    }

    if (GetLocalString(oItem, "ForgeModifications") != "") {
        SetLocalInt(oItem, "Modified", 1);
        DeleteLocalString(oItem, "ForgeModifications");
    }

    int nModified = GetLocalInt(oItem, "Modified");

    if (nModified & 2) {
        if (nBaseType == BASE_ITEM_ARMOR && !(nModified & 65536))
            return sRes;

        /* fix full Silence immunity on randomized items */
        if (FindSubString(GetLocalString(oItem, "Modifications"), " 2,217,56,0,0,255,0") >= 0) {
            WriteTimestampedLogEntry("UPDATEITEMS : " + GetName(GetItemPossessor(oItem)) + " : " + GetName(oItem) + " : fixing full Silence immunity");

            string sMods = GetLocalString(oItem, "Modifications");

            sMods = ReplaceString(sMods, " 2,217,56,0,0,255,0", " 2,53,0,33,150,255,0", TRUE);
            SetLocalString(oItem, "Modifications", sMods);

            itemproperty ip;

            for (ip = GetFirstItemProperty(oItem); GetIsItemPropertyValid(ip); ip = GetNextItemProperty(oItem)) {
                if (GetItemPropertyType(ip) == 217 && GetItemPropertySubType(ip) == 56)
                    RemoveItemProperty(oItem, ip);
            }

            ip = ItemPropertySpellImmunitySpecific(150);
            AddItemProperty(DURATION_TYPE_PERMANENT, ip, oItem);
        }
    }

    return "";
}


void TagDupes (object oPC, string sUniqueID, int nDupes) {
    int i;
    object oItem;

    for (i = 0; i < NUM_INVENTORY_SLOTS; i++) {
        oItem = GetItemInSlot(i, oPC);

        if (GetIsObjectValid(oItem) && GetLocalString(oItem, "UNIQUE_ID") == sUniqueID) {
            DupeAlert(oPC, oItem);

            if (--nDupes < 1)
                return;
        }
    }

    oItem = GetFirstItemInInventory(oPC);

    while (GetIsObjectValid(oItem)) {
        if (GetLocalString(oItem, "UNIQUE_ID") == sUniqueID) {
            DupeAlert(oPC, oItem);

            if (--nDupes < 1)
                return;
        }

        oItem = GetNextItemInInventory(oPC);
    }
}


void main () {
    int i, nDupes, nArtifacts = 0, nCount = 0;
    int bDay = GetIsDay();
    string sRes, sUniqueID;
    object oItem, oMod = GetModule(), oArea = GetArea(OBJECT_SELF);

    if (!GetIsObjectValid(OBJECT_SELF) || GetIsDM(OBJECT_SELF))
        return;

    if (!GetIsObjectValid(oArea) || GetTag(oArea) == "voyage") {
        DelayCommand(5.0, main());
        return;
    }

    HashSetDestroy(oMod, "DupeID");
    HashSetCreate(oMod, "DupeID");

    for (i = 0; i < NUM_INVENTORY_SLOTS; i++) {
        oItem = GetItemInSlot(i, OBJECT_SELF);

        if (GetIsObjectValid(oItem)) {
            if (bDay && GetStringLeft(GetTag(oItem), 4) == "asdf")
                sRes = "drowdust";
            else
                sRes = GetItemUpdate(oItem);

            if (sRes != "") {
                ReplaceItem(OBJECT_SELF, oItem, sRes);

                ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneImmobilize(), OBJECT_SELF, 2.0);
                DelayCommand(1.0, main());

                return;
            }

            if ((sUniqueID = GetLocalString(oItem, "UNIQUE_ID")) != "")
                HashSetSetLocalInt(oMod, "DupeID", sUniqueID,
                    HashSetGetLocalInt(oMod, "DupeID", sUniqueID) + 1);

            if (GetLocalInt(oItem, "Artifact"))
                nArtifacts++;

        }
    }

    oItem = GetFirstItemInInventory(OBJECT_SELF);

    while (GetIsObjectValid(oItem)) {
        if (!GetItemCursedFlag(oItem) || GetItemIsStackable(oItem))
            nCount++;

        sRes = GetItemUpdate(oItem);

        if (sRes != "") {
            ReplaceItem(OBJECT_SELF, oItem, sRes);

            ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneImmobilize(), OBJECT_SELF, 2.0);
            DelayCommand(1.0, main());

            return;
        }

        if ((sUniqueID = GetLocalString(oItem, "UNIQUE_ID")) != "")
            HashSetSetLocalInt(oMod, "DupeID", sUniqueID,
                HashSetGetLocalInt(oMod, "DupeID", sUniqueID) + 1);

        if (GetLocalInt(oItem, "Artifact"))
            nArtifacts += GetItemStackSize(oItem);

        oItem = GetNextItemInInventory(OBJECT_SELF);
    }

    string sKey = HashSetGetFirstKey(oMod, "DupeID");

    while (sKey != "") {
        if ((nDupes = HashSetGetLocalInt(oMod, "DupeID", sKey)) > 1)
            DelayCommand(0.1, TagDupes(OBJECT_SELF, sKey, nDupes - 1));

        sKey = HashSetGetNextKey(oMod, "DupeID");
    }

    HashSetDestroy(oMod, "DupeID");

    if (nArtifacts > 1) {
        DelayCommand(0.0, ArtifactExplode(OBJECT_SELF));
        return;
    }


    if (GetTag(oArea) == "DocksofAscension" || GetTag(oArea) == "TownofAscension") {
        if (nCount > 150 && !VerifyAdminKey(OBJECT_SELF)) {
            location lBurdened = GetLocation(GetWaypointByTag("burdened"));

            DelayCommand(3.0, ForceJump(OBJECT_SELF, lBurdened));
            return;
        }
    }
}
[\\code]

Funky
               
               

               


                     Modifié par FunkySwerve, 16 juin 2011 - 07:12 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0


               Oooooh. So what you want to do is compare all the items the player has to all the blueprints of the module items. If the player has items that don't match any of the blueprints, then get rid of it?

Ewww. As Funky stated, "quite a pain". Yeah I don't think there is any easy way to do this with vanilla NWN. Maybe NWNx and that would be Funky's department. If you did it without NWNx you would have no choice but to do something with all the items in a list to compare player items to.

One other option if you are more concerned with certain item properties than you are with the items, you could do a one time OnAcquire or a DM widget that could loop through items and remove certain illegal item properties.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0


               Goodness gracious Funky that is some script. Ahh Encumbria, what a wonderful place to visit ;p. Since this would not be for a PoA server obviously alot of the lines in the script would not apply. I take it, Funky, you think I (or more likely a competent scripter) could modify that script to pertain to this particular PW?

Also by "indicating the need for an initial all items scan" are you refering to that script or something else? And I am fairly certain that the item banking is resref based. It wont store items if it doesn't have a blueprint for them, and already has a function for updating them to the current state. Subsequently it is the items on PC's that are more of the problem now that I think on it. Which also gives me an idea, that perhaps given how the item bank already functions, when I first import a players characters into the server vault (fromthe old one to a new one) I could somehow dump all their items in the item vault, thereby updating them (and removing any that don't have blueprints)?

Alternatively short of a full server vault wipe, I wonder if it is possible to do just an item wipe on the server vault?

Ghost, yes that is what I was thinking based off of Terrorble's idea. I do have NWNX installed locally, and when I put the mod on a server it will also, as well as a MySQL database. (FYI, this is a WIP currently, but I have found a server host (I think), and am in the process of getting the Mod ready prior to launching.

A DM widget is an interesting idea also, and would work for some things like removing improved evasion, however for others it is more complicated in that the property is allowed, but only at a certain level (e.g. only 10% vs one dmg type is allowed on an item, but some people have gear with much more than that.)
               
               

               


                     Modifié par Lazarus Magni, 16 juin 2011 - 08:09 .