RATDOG/_module/nss/prc_ilr.nss
Jaysyn904 6807c775b4 Tweaked respawn points
Tweaked respawn points.  Tweaked ILR.  Full compile.
2023-01-02 16:21:54 -05:00

298 lines
11 KiB
Plaintext

//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;
}