2026/01/08 Update
Hexblade shouldn't get Medium Armor prof. Weapon Specialization Whip isn't a Warblade bonus feat. Reorganized packages.2da. Fixed potential issue with SetCompositeBonusT(). Added materials iprops to material based crafting. Fixed bug w/ DoTrip(). Added heartbeat script to Monk to properly handle monk sizes. Cleaned up PRCGetCreatureSize(). Set Shielded Casting to use TagItemProperty(). Archivist now has a Lore check to learn spells from scrolls. Set Dragonfire Strike to use TagItemProperty(). Setup Forsaker to use TagItemProperty(). Fixed distance mismatch with Necrocarnum Shroud. Added too much debugging for the unarmed stuff. Cloudkill now obeys Mastery of Shapes.
This commit is contained in:
@@ -96,7 +96,36 @@ void main()
|
||||
SendMessageToPC(oPC, GetStringByStrRef(53308));//"You already have that spell in your spellbook."
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Make a Lore check to learn the spell
|
||||
string sSpellLevel = Get2DACache("spells", "Cleric", nSpellID);
|
||||
nSpellLevel = StringToInt(sSpellLevel);
|
||||
// If no cleric level, check innate level
|
||||
if (nSpellLevel == 0)
|
||||
nSpellLevel = StringToInt(Get2DACache("spells", "Innate", nSpellID));
|
||||
|
||||
int nDC = 15 + nSpellLevel;
|
||||
|
||||
// Check for previous failed attempts
|
||||
string sFailVar = "PRC_Archivist_Fail_" + IntToString(nSpellID);
|
||||
int nFailedLore = GetPersistantLocalInt(oPC, sFailVar);
|
||||
int nCurrentLore = GetSkillRank(SKILL_LORE, oPC);
|
||||
|
||||
// If failed before and Lore hasn't improved, deny attempt
|
||||
if (nFailedLore > 0 && nCurrentLore <= nFailedLore)
|
||||
{
|
||||
FloatingTextStringOnCreature("You must improve your Lore skill before attempting to learn this spell again.", oPC, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!GetPRCIsSkillSuccessful(oPC, SKILL_LORE, nDC))
|
||||
{
|
||||
// Store the Lore rank at time of failure
|
||||
SetPersistantLocalInt(oPC, sFailVar, nCurrentLore);
|
||||
FloatingTextStringOnCreature("Lore check failed (DC " + IntToString(nDC) + "). You cannot learn this spell.", oPC, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
//destroy the scroll
|
||||
int nStack = GetNumStackedItems(oScroll);
|
||||
if (nStack > 1)
|
||||
|
||||
@@ -1,20 +1,236 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Dragonfire Strike
|
||||
//:: prc_dragfire_atk.nss
|
||||
//::///////////////////////////////////////////////
|
||||
/*
|
||||
Handles converting the damage on Dragonfire Strike
|
||||
and similar feats
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Fox
|
||||
//:: Created On: Nov 23, 2007
|
||||
//:://////////////////////////////////////////////
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Dragonfire Strike
|
||||
//:: prc_dragfire_atk.nss
|
||||
//::///////////////////////////////////////////////
|
||||
/*
|
||||
Handles converting the damage on Dragonfire Strike
|
||||
and similar feats
|
||||
*/
|
||||
//:://////////////////////////////////////////////
|
||||
//:: Created By: Fox
|
||||
//:: Created On: Nov 23, 2007
|
||||
//::
|
||||
//:: Updated by: Jaysyn
|
||||
//:: Updated on: 2026-01-08 10:03:33
|
||||
//::
|
||||
//:: Added ItemProperty tagging and constants.
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "prc_inc_sneak"
|
||||
|
||||
// Constants
|
||||
const float DRAGONFIRE_DURATION = 99999.0;
|
||||
const string DRAGONFIRE_TAG = "DragonfireStrike";
|
||||
|
||||
// Helper function for consistent weapon detection
|
||||
int IsDragonfireWeapon(object oItem, object oPC)
|
||||
{
|
||||
return (oItem == GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC) ||
|
||||
(oItem == GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC) && !GetIsShield(oItem)) ||
|
||||
GetWeaponRanged(oItem));
|
||||
}
|
||||
|
||||
// Helper function to safely add properties to ammo
|
||||
void AddAmmoProperties(object oPC, int nPropertyType, int nPropertyParam1)
|
||||
{
|
||||
if (!GetWeaponRanged(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC)))
|
||||
return; // Only add ammo for ranged weapons
|
||||
|
||||
object oAmmo;
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ip = ItemPropertyOnHitCastSpell(nPropertyType, nPropertyParam1);
|
||||
ip = TagItemProperty(ip, DRAGONFIRE_TAG);
|
||||
IPSafeAddItemProperty(oAmmo, ip, DRAGONFIRE_DURATION, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ip = ItemPropertyOnHitCastSpell(nPropertyType, nPropertyParam1);
|
||||
ip = TagItemProperty(ip, DRAGONFIRE_TAG);
|
||||
IPSafeAddItemProperty(oAmmo, ip, DRAGONFIRE_DURATION, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ip = ItemPropertyOnHitCastSpell(nPropertyType, nPropertyParam1);
|
||||
ip = TagItemProperty(ip, DRAGONFIRE_TAG);
|
||||
IPSafeAddItemProperty(oAmmo, ip, DRAGONFIRE_DURATION, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to safely remove properties from ammo
|
||||
void RemoveAmmoProperties(object oPC)
|
||||
{
|
||||
object oAmmo;
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ipCheck = GetFirstItemProperty(oAmmo);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
if (GetItemPropertyTag(ipCheck) == DRAGONFIRE_TAG)
|
||||
{
|
||||
RemoveItemProperty(oAmmo, ipCheck);
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oAmmo);
|
||||
}
|
||||
}
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ipCheck = GetFirstItemProperty(oAmmo);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
if (GetItemPropertyTag(ipCheck) == DRAGONFIRE_TAG)
|
||||
{
|
||||
RemoveItemProperty(oAmmo, ipCheck);
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oAmmo);
|
||||
}
|
||||
}
|
||||
|
||||
oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC);
|
||||
if (GetIsObjectValid(oAmmo))
|
||||
{
|
||||
itemproperty ipCheck = GetFirstItemProperty(oAmmo);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
if (GetItemPropertyTag(ipCheck) == DRAGONFIRE_TAG)
|
||||
{
|
||||
RemoveItemProperty(oAmmo, ipCheck);
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oAmmo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to add Dragonfire property to weapon
|
||||
void AddDragonfireProperty(object oItem)
|
||||
{
|
||||
itemproperty ip = ItemPropertyOnHitCastSpell(IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1);
|
||||
ip = TagItemProperty(ip, DRAGONFIRE_TAG);
|
||||
IPSafeAddItemProperty(oItem, ip, DRAGONFIRE_DURATION, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
}
|
||||
|
||||
// Helper function to remove Dragonfire property from weapon
|
||||
void RemoveDragonfireProperty(object oItem)
|
||||
{
|
||||
itemproperty ipCheck = GetFirstItemProperty(oItem);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
if (GetItemPropertyTag(ipCheck) == DRAGONFIRE_TAG)
|
||||
{
|
||||
RemoveItemProperty(oItem, ipCheck);
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oItem);
|
||||
}
|
||||
}
|
||||
|
||||
void DoDragonfireSneak(object oPC, object oTarget, object oWeapon)
|
||||
{
|
||||
if(DEBUG) DoDebug("Performing Strike");
|
||||
effect eStrike;
|
||||
int nType = GetDragonfireDamageType(oPC);
|
||||
int nDice = GetTotalSneakAttackDice(oPC);
|
||||
int nSneakDamage = GetSneakAttackDamage(nDice);
|
||||
int nDamage = nSneakDamage;
|
||||
|
||||
struct DamageReducers drTotalReduced = GetTotalReduction(oPC, oTarget, oWeapon);
|
||||
nDamage = nDamage * (100 - drTotalReduced.nPercentReductions) / 100;
|
||||
nDamage -= drTotalReduced.nStaticReductions;
|
||||
if(nDamage < 0) nDamage = 0;
|
||||
effect eHealed = EffectHeal(nDamage);
|
||||
|
||||
if(GetHasFeat(FEAT_DRAGONFIRE_STRIKE, oPC) && GetLocalInt(oPC, "DragonFireOn"))
|
||||
nSneakDamage += d6();
|
||||
if(GetHasFeat(FEAT_IMP_DRAGONFIRE_STRIKE, oPC) && GetLocalInt(oPC, "DragonFireOn"))
|
||||
nSneakDamage += nDice;
|
||||
|
||||
effect eSneakDamage = EffectDamage(nSneakDamage, nType);
|
||||
if(!GetIsImmune(oTarget, IMMUNITY_TYPE_CRITICAL_HIT))
|
||||
eStrike = EffectLinkEffects(eSneakDamage, eHealed);
|
||||
else
|
||||
eStrike = eSneakDamage;
|
||||
SPApplyEffectToObject(DURATION_TYPE_INSTANT, eStrike, oTarget);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int nEvent = GetRunningEvent();
|
||||
if(DEBUG) DoDebug("prc_dragfire_atk running, event: " + IntToString(nEvent));
|
||||
|
||||
object oPC;
|
||||
switch(nEvent)
|
||||
{
|
||||
case EVENT_ONPLAYEREQUIPITEM: oPC = GetItemLastEquippedBy(); break;
|
||||
case EVENT_ONPLAYERUNEQUIPITEM: oPC = GetItemLastUnequippedBy(); break;
|
||||
default: oPC = OBJECT_SELF;
|
||||
}
|
||||
|
||||
object oItem;
|
||||
|
||||
if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
||||
{
|
||||
oItem = GetItemLastEquipped();
|
||||
if(DEBUG) DoDebug("prc_dragfire_atk - OnEquip");
|
||||
|
||||
if(IsDragonfireWeapon(oItem, oPC))
|
||||
{
|
||||
// Add eventhook to the item
|
||||
AddEventScript(oItem, EVENT_ITEM_ONHIT, "prc_dragfire_atk", TRUE, FALSE);
|
||||
|
||||
// Add the OnHitCastSpell: Unique needed to trigger the event
|
||||
AddDragonfireProperty(oItem);
|
||||
|
||||
// Add properties to ammo only for ranged weapons
|
||||
AddAmmoProperties(oPC, IP_CONST_ONHIT_CASTSPELL_ONHIT_UNIQUEPOWER, 1);
|
||||
}
|
||||
}
|
||||
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
||||
{
|
||||
oItem = GetItemLastUnequipped();
|
||||
if(DEBUG) DoDebug("prc_dragfire_atk - OnUnEquip");
|
||||
|
||||
if(IsDragonfireWeapon(oItem, oPC))
|
||||
{
|
||||
// Remove eventhook from the item
|
||||
RemoveEventScript(oItem, EVENT_ITEM_ONHIT, "prc_dragfire_atk", TRUE, FALSE);
|
||||
|
||||
// Remove the temporary OnHitCastSpell: Unique
|
||||
RemoveDragonfireProperty(oItem);
|
||||
|
||||
// Remove properties from ammo
|
||||
RemoveAmmoProperties(oPC);
|
||||
}
|
||||
}
|
||||
else if(nEvent == EVENT_ITEM_ONHIT)
|
||||
{
|
||||
object oTarget = PRCGetSpellTargetObject();
|
||||
oItem = GetSpellCastItem();
|
||||
|
||||
if(!IsDragonfireWeapon(oItem, oPC))
|
||||
return;
|
||||
|
||||
if(DEBUG) DoDebug("Weapon Used: " + GetName(oItem));
|
||||
if(DEBUG) DoDebug("CanSneakAttack: " + IntToString(GetCanSneakAttack(oTarget, oPC)));
|
||||
if(DEBUG) DoDebug("Dice: " + IntToString(GetTotalSneakAttackDice(oPC)));
|
||||
|
||||
if(GetCanSneakAttack(oTarget, oPC)
|
||||
&& GetTotalSneakAttackDice(oPC)
|
||||
&& GetLocalInt(oPC, "DragonFireOn"))
|
||||
DoDragonfireSneak(oPC, oTarget, oItem);
|
||||
}
|
||||
}
|
||||
|
||||
#include "prc_inc_combat"
|
||||
#include "prc_inc_sneak"
|
||||
|
||||
void DoDragonfireSneak(object oPC, object oTarget, object oWeapon)
|
||||
/* void DoDragonfireSneak(object oPC, object oTarget, object oWeapon)
|
||||
{
|
||||
if(DEBUG) DoDebug("Performing Strike");
|
||||
effect eStrike;
|
||||
@@ -132,4 +348,4 @@ void main()
|
||||
&& GetLocalInt(oPC, "DragonFireOn"))
|
||||
DoDragonfireSneak(oPC, oTarget, oItem);
|
||||
}
|
||||
}
|
||||
} */
|
||||
@@ -1,15 +1,211 @@
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name Forsaker
|
||||
//:: FileName prc_forsaker.nss
|
||||
//:: Created By: Stratosvarious
|
||||
//:: Edited By: Fencas
|
||||
//:://////////////////////////////////////////////
|
||||
#include "prc_inc_function"
|
||||
#include "prc_inc_combat"
|
||||
#include "inc_dynconv"
|
||||
#include "prc_alterations"
|
||||
//::///////////////////////////////////////////////
|
||||
//:: Name Forsaker
|
||||
//:: FileName prc_forsaker.nss
|
||||
//:: Created By: Stratosvarious
|
||||
//:: Edited By: Fencas
|
||||
//:://////////////////////////////////////////////
|
||||
|
||||
#include "prc_inc_function"
|
||||
#include "prc_inc_combat"
|
||||
#include "inc_dynconv"
|
||||
#include "prc_alterations"
|
||||
|
||||
void main()
|
||||
{
|
||||
int nEvent = GetRunningEvent();
|
||||
if(DEBUG) DoDebug("prc_forsaker running, event: " + IntToString(nEvent));
|
||||
|
||||
// Get the PC. This is event-dependent
|
||||
object oPC;
|
||||
switch(nEvent)
|
||||
{
|
||||
case EVENT_ITEM_ONHIT: oPC = OBJECT_SELF; break;
|
||||
case EVENT_ONPLAYEREQUIPITEM: oPC = GetItemLastEquippedBy(); break;
|
||||
case EVENT_ONPLAYERUNEQUIPITEM: oPC = GetItemLastUnequippedBy(); break;
|
||||
case EVENT_ONHEARTBEAT: oPC = OBJECT_SELF; break;
|
||||
|
||||
default:
|
||||
oPC = OBJECT_SELF;
|
||||
}
|
||||
object oItem;
|
||||
object oArmor;
|
||||
object oShield;
|
||||
object oSkin = GetPCSkin(oPC);
|
||||
|
||||
int nSlot;
|
||||
int nForsakerLvl = GetLevelByClass(CLASS_TYPE_FORSAKER, oPC);
|
||||
int nForsakerLvlCheck;
|
||||
int nBonus = nForsakerLvl/2;
|
||||
int nRegen = 1 + nForsakerLvl/4;
|
||||
int nSR = 10 + nForsakerLvl;
|
||||
|
||||
if(nEvent == FALSE)
|
||||
{
|
||||
|
||||
//Check if level up bonus has already been chosen and given for any of past Forsaker levels
|
||||
for(nForsakerLvlCheck=1; nForsakerLvlCheck <= nForsakerLvl; nForsakerLvlCheck++)
|
||||
{
|
||||
if(!GetPersistantLocalInt(oPC, "ForsakerBoost"+IntToString(nForsakerLvlCheck)))
|
||||
{
|
||||
//Level up box for stat bonus
|
||||
AssignCommand(oPC, ClearAllActions(TRUE));
|
||||
SetPersistantLocalInt(oPC,"ForsakerBoostCheck",nForsakerLvlCheck);
|
||||
StartDynamicConversation("prc_forsake_abil", oPC, DYNCONV_EXIT_NOT_ALLOWED, FALSE, TRUE, oPC);
|
||||
}
|
||||
}
|
||||
|
||||
//Fast healing 1 (+1 each 4 levels)
|
||||
SetCompositeBonus(oSkin,"ForsakerFH",nRegen,ITEM_PROPERTY_REGENERATION);
|
||||
|
||||
//SR = 10 + Forsaker level
|
||||
IPSafeAddItemProperty(oSkin, ItemPropertyBonusSpellResistance(GetSRByValue(nSR)), 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
//DR starting on level 2 = (level+1)/(Level/2)
|
||||
if (nForsakerLvl >=2) ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectDamageReduction((nForsakerLvl+1),(nForsakerLvl/2)),oPC);
|
||||
|
||||
//Natural AC increase by CON starting on level 3
|
||||
if (nForsakerLvl >= 3)
|
||||
{
|
||||
effect eEffect1 = EffectACIncrease(GetAbilityModifier(ABILITY_CONSTITUTION, oPC), AC_NATURAL_BONUS);
|
||||
eEffect1 = ExtraordinaryEffect(eEffect1);
|
||||
eEffect1 = TagEffect(eEffect1, "EffectToughDefense");
|
||||
|
||||
//Remove any prior bonus to avoid duplication
|
||||
effect eCheckEffect = GetFirstEffect(oPC);
|
||||
while (GetIsEffectValid(eCheckEffect))
|
||||
{
|
||||
if(GetEffectTag(eCheckEffect) == "EffectToughDefense") RemoveEffect(oPC, eCheckEffect);
|
||||
eCheckEffect = GetNextEffect(oPC);
|
||||
}
|
||||
|
||||
//Give player the bonus
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect1, oPC);
|
||||
}
|
||||
|
||||
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
|
||||
{
|
||||
// REMOVED: Aggressive inventory scanning that was removing all magical items
|
||||
// This was causing permanent property loss for players
|
||||
// The Forsaker class should still prevent magical item usage through equip events
|
||||
|
||||
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3)) //If it is unarmed, give DR bypass
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
|
||||
}
|
||||
}
|
||||
// Hook in the events, needed from level 1 for Magic Hatred
|
||||
if(DEBUG) DoDebug("prc_forsaker: Adding eventhooks");
|
||||
AddEventScript(oPC, EVENT_ONPLAYEREQUIPITEM, "prc_forsaker", TRUE, FALSE);
|
||||
AddEventScript(oPC, EVENT_ONPLAYERUNEQUIPITEM, "prc_forsaker", TRUE, FALSE);
|
||||
}
|
||||
// We are called from the OnPlayerEquipItem eventhook. Handle magical item restriction
|
||||
else if(nEvent == EVENT_ONPLAYEREQUIPITEM)
|
||||
{
|
||||
oPC = GetItemLastEquippedBy();
|
||||
oItem = GetItemLastEquipped();
|
||||
if(DEBUG) DoDebug("prc_forsaker - OnEquip\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oItem = " + DebugObject2Str(oItem) + "\n");
|
||||
|
||||
if(!GetHasFeat(FEAT_VOWOFPOVERTY,oPC))
|
||||
{
|
||||
// Check if item is a creature item - if so, skip magical item check
|
||||
int nItemType = GetBaseItemType(oItem);
|
||||
if(nItemType == BASE_ITEM_CBLUDGWEAPON ||
|
||||
nItemType == BASE_ITEM_CPIERCWEAPON ||
|
||||
nItemType == BASE_ITEM_CREATUREITEM ||
|
||||
nItemType == BASE_ITEM_CSLASHWEAPON ||
|
||||
nItemType == BASE_ITEM_CSLSHPRCWEAP)
|
||||
{
|
||||
// Item is a creature weapon, allow it
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the item being equipped is magical
|
||||
// Only check the item being equipped, not entire inventory
|
||||
int bIsMagical = FALSE;
|
||||
itemproperty ipCheck = GetFirstItemProperty(oItem);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
// Skip protected properties
|
||||
if(GetItemPropertyTag(ipCheck) != "Tag_PRC_OnHitKeeper")
|
||||
{
|
||||
bIsMagical = TRUE;
|
||||
break;
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oItem);
|
||||
}
|
||||
|
||||
// If item is magical and not a torch, unequip it
|
||||
if(bIsMagical && GetResRef(oItem) != "nw_it_torch001")
|
||||
{
|
||||
AssignCommand(oPC, ClearAllActions(TRUE));
|
||||
AssignCommand(oPC, ActionUnequipItem(oItem));
|
||||
FloatingTextStringOnCreature(GetName(oItem)+" is a magical item!", oPC, FALSE);
|
||||
}
|
||||
// If non-magical weapon and Forsaker has DR bypass, add bonuses
|
||||
else if(!bIsMagical && (IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem)) && (nForsakerLvl >= 3))
|
||||
{
|
||||
// Add DR bypass bonuses to non-magical weapons
|
||||
itemproperty ipAttack = ItemPropertyAttackBonus(nBonus);
|
||||
ipAttack = TagItemProperty(ipAttack, "ForsakerDRBypass");
|
||||
IPSafeAddItemProperty(oItem, ipAttack, 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
itemproperty ipPenalty = ItemPropertyAttackPenalty(nBonus);
|
||||
ipPenalty = TagItemProperty(ipPenalty, "ForsakerDRBypass");
|
||||
IPSafeAddItemProperty(oItem, ipPenalty, 99999.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING, FALSE, FALSE);
|
||||
|
||||
// Remove unarmed bonus
|
||||
effect eLoop = GetFirstEffect(oPC);
|
||||
while(GetIsEffectValid(eLoop))
|
||||
{
|
||||
if(GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_INCREASE
|
||||
|| GetEffectType(eLoop) == EFFECT_TYPE_ATTACK_DECREASE) RemoveEffect(oPC,eLoop);
|
||||
eLoop = GetNextEffect(oPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We are called from the OnPlayerUnEquipItem eventhook. Clean up Forsaker properties
|
||||
else if(nEvent == EVENT_ONPLAYERUNEQUIPITEM)
|
||||
{
|
||||
oPC = GetItemLastUnequippedBy();
|
||||
oItem = GetItemLastUnequipped();
|
||||
if(DEBUG) DoDebug("prc_forsaker - OnUnEquip\n"
|
||||
+ "oPC = " + DebugObject2Str(oPC) + "\n"
|
||||
+ "oItem = " + DebugObject2Str(oItem) + "\n"
|
||||
);
|
||||
|
||||
// Only remove properties that Forsaker actually added
|
||||
if(IPGetIsMeleeWeapon(oItem) || GetWeaponRanged(oItem))
|
||||
{
|
||||
if (nForsakerLvl >= 3)
|
||||
{
|
||||
// Remove only tagged Forsaker properties
|
||||
itemproperty ipCheck = GetFirstItemProperty(oItem);
|
||||
while (GetIsItemPropertyValid(ipCheck))
|
||||
{
|
||||
if (GetItemPropertyTag(ipCheck) == "ForsakerDRBypass")
|
||||
{
|
||||
RemoveItemProperty(oItem, ipCheck);
|
||||
}
|
||||
ipCheck = GetNextItemProperty(oItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If now unarmed, give DR bypass back to player
|
||||
if(GetIsUnarmed(oPC) && (nForsakerLvl >= 3))
|
||||
{
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackIncrease(nBonus),oPC);
|
||||
ApplyEffectToObject(DURATION_TYPE_PERMANENT,EffectAttackDecrease(nBonus),oPC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
|
||||
/* void main()
|
||||
{
|
||||
int nEvent = GetRunningEvent();
|
||||
if(DEBUG) DoDebug("prc_forsaker running, event: " + IntToString(nEvent));
|
||||
@@ -173,7 +369,7 @@ void main()
|
||||
if (nForsakerLvl >= 3) RemoveSpecificProperty(oItem, ITEM_PROPERTY_DECREASED_ATTACK_MODIFIER, -1, -1, 1, "", -1, DURATION_TYPE_TEMPORARY);
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
/* // We aren't being called from any event, instead from EvalPRCFeats
|
||||
|
||||
12
nwn/nwnprc/trunk/scripts/prc_monk.nss
Normal file
12
nwn/nwnprc/trunk/scripts/prc_monk.nss
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "prc_inc_unarmed"
|
||||
|
||||
void main()
|
||||
{
|
||||
object oPC = OBJECT_SELF;
|
||||
|
||||
if(GetLevelByClass(CLASS_TYPE_MONK, oPC) > 0)
|
||||
{
|
||||
SetLocalInt(oPC, CALL_UNARMED_FEATS, TRUE);
|
||||
SetLocalInt(oPC, CALL_UNARMED_FISTS, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,9 @@ void main()
|
||||
if (GetIsObjectValid(oMeldshaper) && PRCGetIsAliveCreature(OBJECT_SELF))
|
||||
{
|
||||
int nEssentia = GetEssentiaInvested(oMeldshaper, MELD_NECROCARNUM_SHROUD);
|
||||
float fDist = MetersToFeet(GetDistanceBetween(oMeldshaper, OBJECT_SELF));
|
||||
float nCheck = 5.0 + nEssentia * 5.0;
|
||||
float fDist = GetDistanceBetween(oMeldshaper, OBJECT_SELF);
|
||||
//float fDist = MetersToFeet(GetDistanceBetween(oMeldshaper, OBJECT_SELF));
|
||||
float nCheck = FeetToMeters(5.0 + nEssentia * 5.0);
|
||||
if (nCheck >= fDist && GetHasSpellEffect(MELD_NECROCARNUM_SHROUD, oMeldshaper))
|
||||
{
|
||||
if(PRCGetIsAliveCreature(OBJECT_SELF))
|
||||
|
||||
@@ -15,19 +15,24 @@
|
||||
|
||||
#include "prc_inc_unarmed"
|
||||
|
||||
void main()
|
||||
void main()
|
||||
{
|
||||
//PrintString("Executing unarmed_caller");
|
||||
int bCont = FALSE;
|
||||
if(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FEATS))
|
||||
{
|
||||
UnarmedFeats(OBJECT_SELF);
|
||||
bCont = TRUE;
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FISTS))
|
||||
{
|
||||
UnarmedFists(OBJECT_SELF);
|
||||
bCont = TRUE;
|
||||
DoDebug("unarmed_caller: FUNCTION STARTED");
|
||||
DoDebug("unarmed_caller: CALL_UNARMED_FEATS = " + IntToString(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FEATS)));
|
||||
DoDebug("unarmed_caller: CALL_UNARMED_FISTS = " + IntToString(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FISTS)));
|
||||
|
||||
int bCont = FALSE;
|
||||
if(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FEATS))
|
||||
{
|
||||
DoDebug("unarmed_caller: CALLING UnarmedFeats");
|
||||
UnarmedFeats(OBJECT_SELF);
|
||||
bCont = TRUE;
|
||||
}
|
||||
if(GetLocalInt(OBJECT_SELF, CALL_UNARMED_FISTS))
|
||||
{
|
||||
DoDebug("unarmed_caller: CALLING UnarmedFists");
|
||||
UnarmedFists(OBJECT_SELF);
|
||||
bCont = TRUE;
|
||||
}
|
||||
|
||||
if(bCont)
|
||||
|
||||
Reference in New Issue
Block a user