//PRC Compatible ILR script //Version : 0.7 //Written by: Silvercloud (scl.vcs-online.com) and Ornedan //Heavily modified from: script by Zanth (of the Legends of Cormyr server: http://www.legendsofcormyr.com/) //Usage: Needs to be in onequip script event of your module // // This script uses valuebased ILR checking (which takes into account PRC items), that can be // overridden by usage of the "ilr_custom_override" variable (integer) on an item. // // Additionally it allows for you to set a deity variable called "ilr_deity" (string) so that // only if the player has that Deity name in his deity field will he be able to equip the item. // // And lastly you can forbid by type of item versus deity as well (which you will need to script // by hand) and i have included an example of forbidding short swords to akadi worshippers // // Note: you do NOT need to set the module to item level restrictions on, you just have to put this // script in the onequip script under module properties. // // 0.4 note: should now properly unequip. // 0.5 note: cheat prevention added with thanks to Evergrey. // 0.6 note: changed the values in the file to reflect bioware 2da and ignore projectiles. // 0.7 note: added plot item checking (switch) // // It should be quite easy to add your own checks to this script. // Just add your own restriction block to the main() and make your own // testing function that returns an itemRestriction structure. - Ornedan // // Handling Projectiles - Due to bioware engine auto-equipping feature on projectiles // you could end up with an endless loop,by default the script now ignores // projectiles for ILR (since any single projectile would never amount to more than 300 coins // anyway, it makes sense to ignore it) // Use the switch to determine behaviour if you want it changed - Silvercloud //---------------------SWITCHES-------------------------\\ // Set this to true if you want to completely ignore IRL checking for projectiles. const int IGNORE_PROJECTILES = TRUE; const int CHECK_PLOT_ITEMS = TRUE; //-------------------END SWITCHES------------------------\\ //These two constants are the variables you would set on an item to set it to either override //the value based ilr with this level or deity worshipped item only . const string ILR_VARIABLE_NAME = "ilr_custom_override"; const string ITEM_DEITY_NAME = "ilr_deity"; // A structure for passing data around the functions here. struct itemRestriction{ // This determines whether the wielder is allowed to wield the item // Values to use: // -1 Item use forbidden by this test, stop further testing. // 0 Item use allowed by this test, pass to next test. // 1 Item use allowed by this test, stop further testing. int nAllow; // Message to send to the equipping PC. This is ignored if nAllow is 0. string sMessage; }; void actionForceUnequipItem(object oItem, object oPlayer, string sMessage); int GetIsInstanceOfPRCItem(string sResRef); struct itemRestriction GetDeityRestriction(string sDeity, object oItem, object oPC); struct itemRestriction GetItemLevelRestriction(object oItem, object oPC); void main() { object oPC = GetPCItemLastEquippedBy(); object oItem = GetPCItemLastEquipped(); int iTyp = GetBaseItemType(oItem); // Handle special PRC class items string sResRef = GetResRef(oItem); if(GetIsInstanceOfPRCItem(sResRef)) return; if (IGNORE_PROJECTILES) { if(iTyp == BASE_ITEM_ARROW)return; if(iTyp == BASE_ITEM_BOLT)return; if(iTyp == BASE_ITEM_BULLET)return; if(iTyp == BASE_ITEM_DART)return; if(iTyp == BASE_ITEM_SHURIKEN)return; if(iTyp == BASE_ITEM_THROWINGAXE)return; } // DMs get to equip whatever they like if(!GetIsDM(oPC) && GetIsPC(oPC)) { struct itemRestriction Result; // Example restriction block /* dataType Foo = GetData(oPC); Result = GetSomeRestriction(foo, oItem, oPC); switch(Result.nAllow){ case -1: actionForceUnequipItem(oItem, oPC, Result.sMessage); case 0: break; case 1: if(Result.sMessage != "") SendMessageToPC(oPC, Result.sMessage); return; } */ // Handle deity restriction string sDeity = GetDeity(oPC); Result = GetDeityRestriction(sDeity, oItem, oPC); switch(Result.nAllow){ case -1: actionForceUnequipItem(oItem, oPC, (Result.sMessage != "" ? Result.sMessage : sDeity + " does not allow you to wield " + GetName(oItem))); case 0: break; case 1: if(Result.sMessage != "") SendMessageToPC(oPC, Result.sMessage); return; } // Handle restriction by item level Result = GetItemLevelRestriction(oItem, oPC); switch(Result.nAllow){ case -1: actionForceUnequipItem(oItem, oPC, Result.sMessage); case 0: break; case 1: if(Result.sMessage != "") SendMessageToPC(oPC, Result.sMessage); return; } } } /* Makes the player unequip the given item and sends any non-empty sMessage to * them. */ void actionForceUnequipItem(object oItem, object oPlayer, string sMessage = "") { if(sMessage != "") SendMessageToPC(oPlayer, sMessage); //Brute force unequip makes it virtually impossible to bypass and cheat. DelayCommand(0.5, AssignCommand(oPlayer, ActionUnequipItem(oItem))); DelayCommand(0.8, AssignCommand(oPlayer, ActionUnequipItem(oItem))); DelayCommand(1.1, AssignCommand(oPlayer, ActionUnequipItem(oItem))); DelayCommand(1.4, AssignCommand(oPlayer, ActionUnequipItem(oItem))); } /* This checks to see if the resref of the given item matches with * the resref of one of the special PRC class items. */ int GetIsInstanceOfPRCItem(string sResRef) { if(sResRef == "base_prc_skin") return TRUE; if(sResRef == "pnp_shft_tstpkup") return TRUE; if(sResRef == "listenerhide") return TRUE; if(sResRef == "shifterhide") return TRUE; if(sResRef == "lichamulet") return TRUE; if(sResRef == "soul_gem") return TRUE; if(sResRef == "platinumarmor4") return TRUE; if(sResRef == "platinumarmor6") return TRUE; if(sResRef == "platinumarmor8") return TRUE; if(sResRef == "wp_arr_imbue_1") return TRUE; if(sResRef == "runescarreddagge") return TRUE; if(sResRef == "codi_mw_katana") return TRUE; if(sResRef == "codi_mw_short") return TRUE; return FALSE; } /* Checks to see whether the deity lets the player use the item. * Returned results: * -1 The deity forbids the use of the item. The player cannot wield * it, no matter what. * 0 The deity does not care one way or another. Other limitations * apply as normal. * 1 The deity helps the player wield the item. They can wield it * even if they normally could not. */ struct itemRestriction GetDeityRestriction(string sDeity, object oItem, object oPC) { struct itemRestriction Result; Result.nAllow = 0; Result.sMessage = ""; //In case there is a special message. sDeity = GetStringLowerCase(sDeity); /* Do your checks here */ //example of forbidding short swords to akadi worshippers /* if(sDeity == "akadi" && GetBaseItemType(oItem) == BASE_ITEM_SHORTSWORD) { Result.nAllow = -1; Result.sMessage = "Akadi forbids the use of this type of item." } */ // See if the item is limited to followers of a single deity only // and if so, whether the player follows said deity string sItemDeity = GetStringLowerCase(GetLocalString(oItem, ITEM_DEITY_NAME)); if(sItemDeity != "") { if(sItemDeity != sDeity) { Result.nAllow = -1; Result.sMessage = "This item is restricted to followers of " + sItemDeity + "."; } } return Result; } struct itemRestriction GetItemLevelRestriction(object oItem, object oPC) { struct itemRestriction Result; Result.nAllow = 0; Result.sMessage = ""; int iItemLevel = 1; int iClassLevel = GetLevelByPosition(1,oPC) + GetLevelByPosition(2, oPC) + GetLevelByPosition(3, oPC); if(GetLocalInt(oItem, ILR_VARIABLE_NAME)) { iItemLevel = GetLocalInt(oItem, ILR_VARIABLE_NAME); } else { int iGPValue = GetGoldPieceValue(oItem) / 4; // Code to check for plotitem and restrict it by its internal value: // only runs if set (=default) if (CHECK_PLOT_ITEMS) { if (GetPlotFlag(oItem) == TRUE) { SetPlotFlag(oItem, FALSE); int iGPValue = GetGoldPieceValue(oItem) / 4; SetPlotFlag(oItem, TRUE); } } if (iGPValue > 4000000) iItemLevel = 40; else if (iGPValue > 3800000) iItemLevel = 39; else if (iGPValue > 3600000) iItemLevel = 38; else if (iGPValue > 3400000) iItemLevel = 37; else if (iGPValue > 3200000) iItemLevel = 36; else if (iGPValue > 3000000) iItemLevel = 35; else if (iGPValue > 2800000) iItemLevel = 34; else if (iGPValue > 2600000) iItemLevel = 33; else if (iGPValue > 2400000) iItemLevel = 32; else if (iGPValue > 2200000) iItemLevel = 31; else if (iGPValue > 2000000) iItemLevel = 30; else if (iGPValue > 1800000) iItemLevel = 29; else if (iGPValue > 1600000) iItemLevel = 28; else if (iGPValue > 1400000) iItemLevel = 27; else if (iGPValue > 1200000) iItemLevel = 26; else if (iGPValue > 1000000) iItemLevel = 25; else if (iGPValue > 750000) iItemLevel = 24; else if (iGPValue > 500000) iItemLevel = 23; else if (iGPValue > 250000) iItemLevel = 22; else if (iGPValue > 130000) iItemLevel = 21; else if (iGPValue > 110000) iItemLevel = 20; else if (iGPValue > 90000) iItemLevel = 19; else if (iGPValue > 75000) iItemLevel = 18; else if (iGPValue > 65000) iItemLevel = 17; else if (iGPValue > 50000) iItemLevel = 16; else if (iGPValue > 40000) iItemLevel = 15; else if (iGPValue > 35000) iItemLevel = 14; else if (iGPValue > 30000) iItemLevel = 13; else if (iGPValue > 25000) iItemLevel = 12; else if (iGPValue > 19500) iItemLevel = 11; else if (iGPValue > 15000) iItemLevel = 10; else if (iGPValue > 12000) iItemLevel = 9; else if (iGPValue > 9000) iItemLevel = 8; else if (iGPValue > 6500) iItemLevel = 7; else if (iGPValue > 5000) iItemLevel = 6; else if (iGPValue > 3500) iItemLevel = 5; else if (iGPValue > 2500) iItemLevel = 4; else if (iGPValue > 1500) iItemLevel = 3; else if (iGPValue > 1000) iItemLevel = 2; } if (iItemLevel > iClassLevel) { Result.nAllow = -1; Result.sMessage = "You are not high enough level to equip " + GetName(oItem) + ", you must be at least level: " + IntToString(iItemLevel) + "."; } return Result; }