Animal, Beast, Magical Beast, Vermin & Ooze have no reason to be set to PlayerClass. Added default (Blaster) gear, levelup and skill package for Warlock. Added missing Weapon Specialization for "new" weapons to Warblade's class feat 2DA. Fixed Light Lance duped name in feat.2da. Tweaked defaults on personal_switch.2da Updated PRC8 version in prc_inc_switch. Fixed token error in Create Tattoo dialogue. Updated IoDM's Dragon Fear Aura to give immunity to target for 24 hours if they pass the will save. Fixed issue with classes not being able to cast spells in their spellbook from scrolls. Updated nwn_erf & nwn_gff.
376 lines
18 KiB
Plaintext
376 lines
18 KiB
Plaintext
//::///////////////////////////////////////////////
|
|
//:: OnAcquireItem eventscript
|
|
//:: prc_onaquire
|
|
//:://////////////////////////////////////////////
|
|
#include "prc_alterations"
|
|
#include "prc_craft_inc"
|
|
//#include "psi_inc_manifest"
|
|
|
|
void AntiMagicFieldCheck(object oItem, object oCreature)
|
|
{
|
|
int nIP = array_get_size(oItem, "PRC_NPF_ItemList");
|
|
if(GetHasSpellEffect(SPELL_ANTIMAGIC_FIELD, oCreature)
|
|
|| GetHasSpellEffect(POWER_NULL_PSIONICS_FIELD, oCreature))
|
|
{
|
|
if(nIP)
|
|
// itemproperty list already exists - do nothing
|
|
return;
|
|
|
|
//remove ips
|
|
string sIP;
|
|
int nIpCount;
|
|
persistant_array_create(oCreature, "PRC_NPF_ItemList"); //stores object strings
|
|
itemproperty ip = GetFirstItemProperty(oItem);
|
|
while(GetIsItemPropertyValid(ip))
|
|
{
|
|
if(GetItemPropertyDurationType(ip) == DURATION_TYPE_PERMANENT)
|
|
{ //only store the permanent ones as underscore delimited strings
|
|
sIP = IntToString(GetItemPropertyType(ip)) + "_" +
|
|
IntToString(GetItemPropertySubType(ip)) + "_" +
|
|
IntToString(GetItemPropertyCostTableValue(ip)) + "_" +
|
|
IntToString(GetItemPropertyParam1Value(ip));
|
|
if(DEBUG) DoDebug("StoreItemprops: " + GetName(oCreature) + ", " + ObjectToString(oItem) + ", " + sIP);
|
|
array_set_string(oCreature, "PRC_NPF_ItemList", nIpCount++, sIP);
|
|
}
|
|
RemoveItemProperty(oItem, ip);
|
|
ip = GetNextItemProperty(oItem);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!nIP)
|
|
// itemproperty list not found!
|
|
return;
|
|
|
|
//restore ips
|
|
struct ipstruct iptemp;
|
|
itemproperty ip;
|
|
string sIP;
|
|
int i;
|
|
|
|
for(i = 0; i < nIP; i++)
|
|
{
|
|
sIP = array_get_string(oItem, "PRC_NPF_ItemList", i);
|
|
iptemp = GetIpStructFromString(sIP);
|
|
ip = ConstructIP(iptemp.type, iptemp.subtype, iptemp.costtablevalue, iptemp.param1value);
|
|
IPSafeAddItemProperty(oItem, ip, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
|
|
if(DEBUG) DoDebug("RetoreItemprops: " + GetName(GetItemPossessor(oItem)) + ", " + ObjectToString(oItem) + ", " + sIP);
|
|
}
|
|
array_delete(oItem, "PRC_NPF_ItemList");
|
|
}
|
|
}
|
|
|
|
void UpdateIPs(object oItem)
|
|
{
|
|
// Has lookup finished yet?
|
|
if(GetXP(GetObjectByTag("Bioware2DACache")) & 0x01)
|
|
{
|
|
int bAddRestrictions = FALSE;
|
|
int nSpellID;
|
|
|
|
//Set the AMS version of last update
|
|
SetLocalString(oItem, "sb_ver", AMS_VERSION);
|
|
|
|
//remove all class restrictions and mark the spell
|
|
itemproperty ipTest = GetFirstItemProperty(oItem);
|
|
while(GetIsItemPropertyValid(ipTest))
|
|
{
|
|
if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_USE_LIMITATION_CLASS)
|
|
{
|
|
//the scroll/wand had a use limitation
|
|
RemoveItemProperty(oItem, ipTest);
|
|
bAddRestrictions = TRUE;
|
|
}
|
|
else if(GetItemPropertyType(ipTest) == ITEM_PROPERTY_CAST_SPELL)
|
|
{
|
|
nSpellID = StringToInt(Get2DACache("iprp_spells", "SpellIndex", GetItemPropertySubType(ipTest)));
|
|
}
|
|
ipTest = GetNextItemProperty(oItem);
|
|
}
|
|
if(bAddRestrictions)
|
|
{
|
|
int i, nClass, bAdd;
|
|
for(i = 0; i < 36; i++)
|
|
{
|
|
bAdd = FALSE;
|
|
switch(i)
|
|
{
|
|
case 0: nClass = CLASS_TYPE_BARD; break;
|
|
case 1: nClass = CLASS_TYPE_CLERIC; break;
|
|
case 2: nClass = CLASS_TYPE_DRUID; break;
|
|
case 3: nClass = CLASS_TYPE_PALADIN; break;
|
|
case 4: nClass = CLASS_TYPE_RANGER; break;
|
|
case 5: nClass = CLASS_TYPE_SORCERER; break;
|
|
case 6: nClass = CLASS_TYPE_WIZARD; break;
|
|
case 7: nClass = CLASS_TYPE_HARPER; break;
|
|
case 8: nClass = CLASS_TYPE_ASSASSIN; break;
|
|
case 9: nClass = CLASS_TYPE_BLACKGUARD; break;
|
|
case 10: nClass = CLASS_TYPE_OCULAR; break;
|
|
case 11: nClass = CLASS_TYPE_HEXBLADE; break;
|
|
case 12: nClass = CLASS_TYPE_DUSKBLADE; break;
|
|
case 13: nClass = CLASS_TYPE_HEALER; break;
|
|
case 14: nClass = CLASS_TYPE_BEGUILER; break;
|
|
case 15: nClass = CLASS_TYPE_KNIGHT_CHALICE; break;
|
|
case 16: nClass = CLASS_TYPE_VIGILANT; break;
|
|
case 17: nClass = CLASS_TYPE_VASSAL; break;
|
|
case 18: nClass = CLASS_TYPE_SUBLIME_CHORD; break;
|
|
case 19: nClass = CLASS_TYPE_NENTYAR_HUNTER; break;
|
|
case 20: nClass = CLASS_TYPE_SOLDIER_OF_LIGHT; break;
|
|
case 21: nClass = CLASS_TYPE_SHADOWLORD; break;
|
|
case 22: nClass = CLASS_TYPE_JUSTICEWW; break;
|
|
case 23: nClass = CLASS_TYPE_KNIGHT_MIDDLECIRCLE; break;
|
|
case 24: nClass = CLASS_TYPE_DREAD_NECROMANCER; break;
|
|
case 25: nClass = CLASS_TYPE_MYSTIC; break;
|
|
case 26: nClass = CLASS_TYPE_ARCHIVIST; break;
|
|
case 27: nClass = CLASS_TYPE_WITCH; break;
|
|
case 28: nClass = CLASS_TYPE_SHAMAN; break;
|
|
case 29: nClass = CLASS_TYPE_SLAYER_OF_DOMIEL; break;
|
|
case 30: nClass = CLASS_TYPE_SUEL_ARCHANAMACH; break;
|
|
case 31: nClass = CLASS_TYPE_FAVOURED_SOUL; break;
|
|
case 32: nClass = CLASS_TYPE_SHUGENJA; break;
|
|
case 33: nClass = CLASS_TYPE_SOHEI; break;
|
|
case 34: nClass = CLASS_TYPE_WARMAGE; break;
|
|
case 35: nClass = CLASS_TYPE_TEMPLAR; break;
|
|
case 36: nClass = CLASS_TYPE_JUSTICEWW; break;
|
|
case 37: nClass = CLASS_TYPE_BLIGHTER; break;
|
|
case 38: nClass = CLASS_TYPE_SHADOWLORD; break;
|
|
case 39: nClass = CLASS_TYPE_KNIGHT_WEAVE; break;
|
|
case 40: nClass = CLASS_TYPE_CULTIST_SHATTERED_PEAK; break;
|
|
case 41: nClass = CLASS_TYPE_CELEBRANT_SHARESS; break;
|
|
}
|
|
|
|
if(nClass == CLASS_TYPE_ASSASSIN)
|
|
bAdd = Get2DACache("Spells", "Assassin", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_BLACKGUARD)
|
|
bAdd = Get2DACache("Spells", "Blackguard", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_BLIGHTER)
|
|
bAdd = Get2DACache("Spells", "Blighter", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_KNIGHT_CHALICE)
|
|
bAdd = Get2DACache("Spells", "Chalice", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_CULTIST_SHATTERED_PEAK)
|
|
bAdd = Get2DACache("Spells", "Cultist", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_DRUID)
|
|
bAdd = Get2DACache("Spells", "Druid", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_SHADOWLORD)
|
|
bAdd = Get2DACache("Spells", "Telflammar", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_SHAMAN)
|
|
bAdd = Get2DACache("Spells", "Shaman", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_SLAYER_OF_DOMIEL)
|
|
bAdd = Get2DACache("Spells", "Domiel", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_SOHEI)
|
|
bAdd = Get2DACache("Spells", "Sohei", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_SOLDIER_OF_LIGHT)
|
|
bAdd = Get2DACache("Spells", "SoLight", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_HEALER)
|
|
bAdd = Get2DACache("Spells", "Healer", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_KNIGHT_MIDDLECIRCLE)
|
|
bAdd = Get2DACache("Spells", "MiddleCircle", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_NENTYAR_HUNTER)
|
|
bAdd = Get2DACache("Spells", "Nentyar", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_PALADIN)
|
|
bAdd = Get2DACache("Spells", "Paladin", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_RANGER)
|
|
bAdd = Get2DACache("Spells", "Ranger", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_VASSAL)
|
|
bAdd = Get2DACache("Spells", "Bahamut", nSpellID) == "" ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER)
|
|
bAdd = RealSpellToSpellbookID(CLASS_TYPE_SORCERER, nSpellID) == -1 ? FALSE : TRUE;
|
|
else if(nClass == CLASS_TYPE_CLERIC)
|
|
bAdd = Get2DACache("Spells", "Cleric", nSpellID) == "" ? FALSE : TRUE;
|
|
else
|
|
bAdd = RealSpellToSpellbookID(nClass, nSpellID) == -1 ? FALSE : TRUE;
|
|
|
|
if(bAdd)
|
|
AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByClass(nClass), oItem);
|
|
}
|
|
}
|
|
}
|
|
else // Nope, try again later
|
|
{
|
|
DelayCommand(0.2f, UpdateIPs(oItem));
|
|
}
|
|
}
|
|
|
|
void main()
|
|
{
|
|
// Find out the relevant objects
|
|
object oCreature = GetModuleItemAcquiredBy();
|
|
object oItem = GetModuleItemAcquired();
|
|
string sTag = GetTag(oItem);
|
|
|
|
// Do not run for some of the PRC special items
|
|
if(sTag == "PRC_MANIFTOKEN"
|
|
|| sTag == "HideToken"
|
|
|| GetResRef(oItem) == "base_prc_skin")
|
|
return;
|
|
|
|
//if(DEBUG) DoDebug("Running OnAcquireItem, creature = '" + GetName(oCreature) + "' is PC: " + DebugBool2String(GetIsPC(oCreature)) + "; Item = '" + GetName(oItem) + "' - '" + GetTag(oItem) + "'");
|
|
|
|
AntiMagicFieldCheck(oItem, oCreature);
|
|
|
|
int nItemType = GetBaseItemType(oItem);
|
|
|
|
//fix for all-beige 1.67 -> 1.68 cloaks
|
|
//gives them a random color
|
|
if(nItemType == BASE_ITEM_CLOAK)
|
|
{
|
|
if(!GetPRCSwitch(PRC_DYNAMIC_CLOAK_AUTOCOLOUR_DISABLE) && !GetLocalInt(oItem, "CloakDone"))
|
|
{
|
|
//&& GetItemAppearance(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0) == 1
|
|
if(GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH1) == 0
|
|
&& GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH2) == 0
|
|
&& GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1) == 0
|
|
&& GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER2) == 0
|
|
&& GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1) == 0
|
|
&& GetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL2) == 0)
|
|
{
|
|
//pre-1.68 boring bland cloak, colorise it :)
|
|
//move it to temporary storage first
|
|
object oChest = GetObjectByTag("HEARTOFCHAOS");
|
|
DestroyObject(oItem);
|
|
oItem = CopyItem(oItem, oChest, TRUE);
|
|
//set appearance
|
|
//doesnt work yet should do for 1.69
|
|
//DestroyObject(oItem);
|
|
//oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, Random(14)+1, TRUE);
|
|
//set colors
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH1, Random(176), TRUE);
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH2, Random(176), TRUE);
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1, Random(176), TRUE);
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER2, Random(176), TRUE);
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1, Random(176), TRUE);
|
|
DestroyObject(oItem);
|
|
oItem = CopyItemAndModify(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL2, Random(176), TRUE);
|
|
//move it back
|
|
DestroyObject(oItem);
|
|
oItem = CopyItem(oItem, oCreature, TRUE);
|
|
//mark it as set just to be sure
|
|
SetLocalInt(oItem, "CloakDone", TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This is a resource hog. To work around, we assume that it's not going to cause noticeable issues if
|
|
// racial restrictions are only ever expanded when a PC is involved
|
|
if(GetIsPC(oCreature) || GetIsPC(GetMaster(oCreature)) || GetPRCSwitch(PRC_NPC_FORCE_RACE_ACQUIRE))
|
|
ExecuteScript("race_ev_aquire", OBJECT_SELF);
|
|
|
|
// Creatures not related to PCs skip this block, contents are irrelevant for them
|
|
if(GetIsPC(oCreature) || GetIsPC(GetMaster(oCreature)))
|
|
{
|
|
if(GetPRCSwitch(PRC_AUTO_IDENTIFY_ON_ACQUIRE))
|
|
{
|
|
if(!GetIdentified(oItem))
|
|
{
|
|
// No negative numbers, please
|
|
int nLore = PRCMax(0, GetSkillRank(SKILL_LORE, oCreature));
|
|
int nMax = StringToInt(Get2DACache("SkillVsItemCost", "DeviceCostMax", nLore));
|
|
if(nMax == 0)
|
|
nMax = 120000000;
|
|
// Check for the value of the item first.
|
|
SetIdentified(oItem, TRUE);
|
|
int nGP = GetGoldPieceValue(oItem);
|
|
// If oPC has enough Lore skill to ID the item, then do so.
|
|
if(nMax >= nGP)
|
|
{
|
|
string sName = GetName(oItem);
|
|
if(sName != "")
|
|
SendMessageToPC(oCreature, GetStringByStrRef(16826224) + " " + sName + " " + GetStringByStrRef(16826225));
|
|
}
|
|
else
|
|
SetIdentified(oItem, FALSE);
|
|
}
|
|
}
|
|
|
|
if(nItemType == BASE_ITEM_MAGICWAND
|
|
|| nItemType == BASE_ITEM_ENCHANTED_WAND
|
|
|| nItemType == BASE_ITEM_SCROLL
|
|
|| nItemType == BASE_ITEM_SPELLSCROLL
|
|
|| nItemType == BASE_ITEM_ENCHANTED_SCROLL)
|
|
{
|
|
if(!GetPRCSwitch(PRC_SCROLL_AUTOUPDATE_RESTR_DISABLE)
|
|
&& GetLocalString(oItem, "sb_ver") != AMS_VERSION //different Alternate Magic System versions - update IPs
|
|
&& !GetLocalInt(oItem, "ip_lock")) //IPs of wand/scroll were locked in toolset or by script
|
|
{
|
|
DelayCommand(1.0f, UpdateIPs(oItem));//delayed to reduce lag and prevent TMIs
|
|
}
|
|
}
|
|
|
|
//rest kits
|
|
if(GetPRCSwitch(PRC_SUPPLY_BASED_REST))
|
|
ExecuteScript("sbr_onaquire", OBJECT_SELF);
|
|
|
|
//PRC Companion
|
|
//DOA visible dyepot items
|
|
/*if(GetPRCSwitch(MARKER_PRC_COMPANION))
|
|
{
|
|
if(GetBaseItemType(oItem) == BASE_ITEM_MISCSMALL)
|
|
{
|
|
//x2_it_dyec23
|
|
string sTag = GetTag(oItem);
|
|
if(GetStringLeft(sTag, 9) == "x2_it_dye")
|
|
{
|
|
//get the color
|
|
//taken from x2_s3_dyearmour
|
|
// GZ@2006/03/26: Added new color palette support. Note: Will only work
|
|
// if craig updates the in engine functions as well.
|
|
int nColor = 0;
|
|
// See if we find a valid int between 0 and 127 in the last three letters
|
|
// of the tag, use it as color
|
|
int nTest = StringToInt(GetStringRight(sTag,3));
|
|
if (nTest > 0 &&
|
|
nTest < 175 )//magic number, bad!
|
|
nColor = nTest;
|
|
else //otherwise, use last two letters, as per legacy HotU
|
|
nColor = StringToInt(GetStringRight(sTag,2));
|
|
|
|
//use limbo for crafting in
|
|
object oLimbo = GetObjectByTag("HEARTOFCHAOS");
|
|
//create the new one with the same tag as the old
|
|
object oDye = CreateItemOnObject("prccompdye", oLimbo, 1, sTag);
|
|
//ensure old one is cleaned up
|
|
DestroyObject(oItem);
|
|
//if its a metalic dye, modify it to use model 2
|
|
if(GetStringRight(GetStringLeft(sTag, 10), 1) == "m")
|
|
{
|
|
DestroyObject(oDye);
|
|
oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, 2);
|
|
//metal dye color
|
|
DestroyObject(oDye);
|
|
oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1, nColor);
|
|
}
|
|
else
|
|
{
|
|
//standard dye
|
|
DestroyObject(oDye);
|
|
//cloth and leather use same palettee
|
|
oDye = CopyItemAndModify(oDye, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1, nColor);
|
|
}
|
|
//copy the itemprops to cast the dye "spell"
|
|
itemproperty ipTest = GetFirstItemProperty(oItem);
|
|
while(GetIsItemPropertyValid(ipTest))
|
|
{
|
|
AddItemProperty(DURATION_TYPE_PERMANENT, ipTest, oDye);
|
|
ipTest = GetNextItemProperty(oItem);
|
|
}
|
|
//move it back to the player
|
|
CopyItem(oDye, oCreature);
|
|
DestroyObject(oDye);
|
|
}
|
|
}
|
|
}*/
|
|
}// end if - PC or associate of PC
|
|
|
|
// Execute scripts hooked to this event for the creature and item triggering it
|
|
ExecuteAllScriptsHookedToEvent(oCreature, EVENT_ONACQUIREITEM);
|
|
ExecuteAllScriptsHookedToEvent(oItem, EVENT_ITEM_ONACQUIREITEM);
|
|
|
|
// Tag-based scripting hook for PRC items
|
|
SetUserDefinedItemEventNumber(X2_ITEM_EVENT_ACQUIRE);
|
|
ExecuteScript("is_"+sTag, OBJECT_SELF);
|
|
} |