No Arcane Spell Failure for Bards in Light Armor
#1
Posté 18 mai 2011 - 09:15
I haven't sepnt much time trying, but I've tried applying a reduction to arcane spellcasting to a creature skin and equipping that on a PC, however that doesn't seem to work (not sure why though...?).
Has anyone managed to figure this out or have any scripting ideas to make this possible?
#2
Posté 19 mai 2011 - 05:30
Modifié par Ralthis, 19 mai 2011 - 05:30 .
#3
Posté 19 mai 2011 - 10:45
OnPlayerEquipItem/
OnPlayerUnequipItemscripts? The script could check the character for bard levels and check the item to see that it's light armor. Then, set a local on the armor for the current level of the Arcane Spell Failure property, so that armor that normally has reduced arcane failure doesn't lose it when a bard unequips it. (You might also want to change the level-up script to check if a non-bard character adds a bard level while already wearing light armor...) The property could even be added as temporary to make it clear that it's not normally part fo the armor.
I guess this doesn't work as well if you don't want the player to be able to see that the armor has been modified. And, I don't know if there is a good way to keep bards from cheating merchants out of extra gold by directly selling equipped armor...
Modifié par MrZork, 19 mai 2011 - 10:47 .
#4
Posté 20 mai 2011 - 12:40
MrZork wrote...
Could you do this with by adding the Arcane Spell Failure property (of the appropriate amount) to light armors equipped by bards in the module'sOnPlayerEquipItem/OnPlayerUnequipItemscripts? The script could check the character for bard levels and check the item to see that it's light armor. Then, set a local on the armor for the current level of the Arcane Spell Failure property, so that armor that normally has reduced arcane failure doesn't lose it when a bard unequips it. (You might also want to change the level-up script to check if a non-bard character adds a bard level while already wearing light armor...) The property could even be added as temporary to make it clear that it's not normally part fo the armor.
I guess this doesn't work as well if you don't want the player to be able to see that the armor has been modified. And, I don't know if there is a good way to keep bards from cheating merchants out of extra gold by directly selling equipped armor...
I was thinking along similar lines and would just have the armors set to PLOT (toggled when equipped/unequipped) as well to prevent merchant abuses.
#5
Posté 20 mai 2011 - 01:40
MrZork and kalbern, I had thought of that too - but (other than the potential selling exploit issue) we have Item Level Restrictions turned on. So if someone equips that armor and gets the Arcane Spell Failure added to it it could put it over their level. So then if they logout they wouldn't be able to log back in. I should have mentioned we had ILR to begin with since that does unfortunately futher limit scripted options too.
Modifié par Thayan, 20 mai 2011 - 01:46 .
#6
Posté 20 mai 2011 - 08:53
If either of the above are possible you could alter your modules OnPlayerEquip/Unequip to do something kinda like so:
OnPlayerEquip:
void main()
{
object oPC = GetPCItemLastEquippedBy();
int iclass = GetLevelByclass(class_TYPE_BARD, oPC);
if (iclass < 1)return;
object oArmor = GetPCItemLastEquipped();
int iType = GetBaseItemType(oArmor);
if (iType != BASE_ITEM_ARMOR) return;
int iACVal = GetItemACValue(oArmor);
itemproperty ipAdd;
switch (iACVal)
{
case 1: ipAdd = ItemPropertyArcaneSpellFailure(-5);break;
case 2: ipAdd = ItemPropertyArcaneSpellFailure(-10);break;
case 3: ipAdd = ItemPropertyArcaneSpellFailure(-20);break;
case 4: ipAdd = ItemPropertyArcaneSpellFailure(-20);break;
default:return;
}
object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
IPSafeAddItemProperty(oSkin, ipAdd, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
}
OnPlayerUnequip:
#include "x2_inc_itemprop"
void main()
{
object oPC = GetPCItemLastUnequippedBy();
int iclass = GetLevelByclass(class_TYPE_BARD, oPC);
if (iclass < 1)return;
object oArmor = GetPCItemLastUnequipped();
int iType = GetBaseItemType(oArmor);
if (iType != BASE_ITEM_ARMOR) return;
int iACVal = GetItemACValue(oArmor);
object oSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
if (iACVal > 0 && iACVal < 5)
IPRemoveMatchingItemProperties(oSkin, ITEM_PROPERTY_ARCANE_SPELL_FAILURE, DURATION_TYPE_PERMANENT);
}
Hope it helps and good luck.
#7
Posté 21 mai 2011 - 12:27
Link nwn.bioware.com/forums/viewtopic.html
Link nwvault.ign.com/View.php
#8
Posté 21 mai 2011 - 12:53
I tested out the possibility of using the module spellhook and the spellhook fires *after* the arcane spell failure check, so it can't be worked around that way either. Murphy's Law is in effect on this one. I'm not sure what else to try unless anyone knows of a way to trick the system (editting .2da's maybe?) to allow Arcane Spell Failure to be applied to creature skins.
#9
Posté 21 mai 2011 - 01:17
This will allow the ArcaneSpellFailure itemproperty to be put on Creature Hide items.
You must restart the Toolset for the change to take place.
-fox
Modifié par the.gray.fox, 21 mai 2011 - 01:20 .
#10
Posté 21 mai 2011 - 01:21
Thayan wrote...
MrZork and kalbern, I had thought of that too - but (other than the potential selling exploit issue) we have Item Level Restrictions turned on. So if someone equips that armor and gets the Arcane Spell Failure added to it it could put it over their level. So then if they logout they wouldn't be able to log back in. I should have mentioned we had ILR to begin with since that does unfortunately futher limit scripted options too.
So why not check the Armor OnClientLeave and remove the proptrie if they have it. You would also need to modify any scripts yoou have that export the character to also remove it, just incase of a server crash.
#11
Posté 21 mai 2011 - 02:22
Regardless though, I've been able to make considerable progress on the creature skin idea now that gray fox gave me the hint i needed to tell me what I was doing wrong (restart the Toolset dammit. RESTART!)
I need to do a little more testing, but I'm pretty sure with only the server-side modification to the ItemProps.2da I have a working system for this. I will post it after I've tested a bit more and made sure it actually works from client machines that don't have the modification.
#12
Posté 21 mai 2011 - 02:29
#13
Posté 21 mai 2011 - 07:13
Assuming this works OK for others it might be something I'll toss up on the Vault since it requires making item blueprints and editting that ItemProps.2da.
EDIT: And especially considering it now since the code posted here is one huge mess that I don't feel like cleaning up at the moment since these corums can't handle it nicely.
EDIT: What a disaster. Posting code here simply sucks. No other way to describe it without risking a ban. tried some cleanup but I'm calling it quits for tonight. Hopefully it still works for anyone that attempts to try it.
//mod_onequip_bard
/*
D&D 3.5 Rule - No Arcane Spell Failure for Bards in Light Armor
---------------------------------------------------------------
The purpose of this package is to ensure that when a Bard equips light armor they do not suffer arcane spell failure
as per D&D 3.5 rules. This package will work with Item Level Restrictions turned on, and does not require a hak.
Scripts
-----------------
Place the mod_onequip_bardscript in your module's OnEquip event and place the mod_onunequ_bard script in the
module's OnUnequip event, or merge them both with your existing scripts in those events.
.2da Modification
-----------------
In addition to those scripts, you must edit the ItemProps.2da -- row 84 -- column 13_Hide and substitute the **** with
a 1. Make sure you add three spaces after the 1 so the padding in the .2da remains the same. Then, put the ItemProps.2da
in the override folder on the server. You will need to restart your toolset. Once you do, this change will allow you
to add the Arcane Spell Reduction item property to creature skins which is required in the next section.
Item Blueprints
-----------------
After editing the ItemProps.2da, you must create three custom creature skin blueprints in your module. Give the
first Arcane Spell Reduction -5%, the second Arcane Spell Reduction -10%, and the third Arcane Spell Reduction -20%.
These blueprints are necessary because the IPSafeAddItemProperty() function will not add the Arcane Spell Reduction
item property unless it is copire from another item that has it added from the toolset itself. If anyone figures out
a way to get the IPSafeAddItemProperty() function to work without these blueprints though, please let me know!
Thanks to the guys on the forums who helped provide input, scripts snippets, and the ideas to make this possible:
Ralthis, MrZork, kalbaern, GhostOfGod, ShadowM, Axe Murderer (we miss you buddy!) and the.gray.fox
*/
#include "x2_inc_itemprop"
//::///////////////////////////////////////////////////
// int GetItemACBase( object oItem)
//::///////////////////////////////////////////////////
// Parameters
// - oItem: armor to be evaluated
//
// Returns the base AC of oItem or -1 on error
// * Returns: base AC of armor (0 - 8)
// * OnError: -1 if oItem is invalid or not armor
//::///////////////////////////////////////////////////
int GetItemACBase( object oItem);
int GetItemACBase( object oItem)
{ // if oItem is not armor then return an error
if( !GetIsObjectValid( oItem) || (GetBaseItemType( oItem) != BASE_ITEM_ARMOR)) return -1;
// Get the torso model number
int nTorso = GetItemAppearance( oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO);
// Read 2DA for base AC
// Can also use "parts_chest" which returns it as a "float"
string sACBase = Get2DAString( "des_crft_appear", "BaseAC", nTorso);
// return base AC
return StringToInt( sACBase);
}
void main()
{
object oPC = GetPCItemLastEquippedBy();
object oItem = GetPCItemLastEquipped();
if (GetLevelByclass(class_TYPE_BARD, oPC) && GetBaseItemType(oItem) == BASE_ITEM_ARMOR) { //Is this a bard equipping armor?
int iACVal = GetItemACBase(oItem);
if (iACVal > 0 && iACVal < 5) { //Only apply the Arcane Spellcasting Reduction if they equipped light armor
string sArcaneSkinResRef = "arcaneskin_20"; //-20% Arcane Spellcasting Reduction for AC 3 and AC 4 armor
if (iACVal == 2) sArcaneSkinResRef = "arcaneskin_10"; //-10% Arcane Spellcasting Reduction for AC 2 armor
if (iACVal == 1) sArcaneSkinResRef = "arcaneskin_5"; //-5% Arcane Spellcasting Reduction for AC 1 armor
object oEquippedSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
if (oEquippedSkin != OBJECT_INVALID) { //If they already have a creature skin equipped, copy the properties from a dummy arcane skin
object oArcaneFailureReductionSkin = CreateObject(OBJECT_TYPE_ITEM, sArcaneSkinResRef, GetLocation(oPC));
itemproperty ipProp = GetFirstItemProperty(oArcaneFailureReductionSkin); //Make sure Arcane Spellcasting Reduction is the ONLY property on the skin
IPSafeAddItemProperty(oEquippedSkin, ipProp, 0.0, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
DestroyObject(oArcaneFailureReductionSkin);
}
else { //If they don't have a creatue skin equipped, just create the appropriate arcane skin and equip it on them
object oArcaneFailureReductionSkin = CreateItemOnObject(sArcaneSkinResRef, oPC);
SetIdentified(oArcaneFailureReductionSkin, TRUE);
AssignCommand(oPC, ActionEquipItem(oArcaneFailureReductionSkin,INVENTORY_SLOT_CARMOUR));
}
DelayCommand(0.5, SendMessageToPC(oPC, "As a Bard you suffer no increase to Arcane Spell Failure wearing this light armor."));
}
}
}//mod_onunequ_bard
/*
D&D 3.5 Rule - No Arcane Spell Failure for Bards in Light Armor
---------------------------------------------------------------
Place this script in the modules OnUnequip event, or merge it with your existing script. The purpose of this script
is to ensure that when a Bard unequips light armor they the arcane spell failure applied to their creature skin removed.
*/
#include "x2_inc_itemprop"
//::///////////////////////////////////////////////////
// int GetItemACBase( object oItem)
//::///////////////////////////////////////////////////
// Parameters
// - oItem: armor to be evaluated
//
// Returns the base AC of oItem or -1 on error
// * Returns: base AC of armor (0 - 8)
// * OnError: -1 if oItem is invalid or not armor
//::///////////////////////////////////////////////////
int GetItemACBase( object oItem);
int GetItemACBase( object oItem)
{ // if oItem is not armor then return an error
if( !GetIsObjectValid( oItem) || (GetBaseItemType( oItem) != BASE_ITEM_ARMOR)) return -1;
// Get the torso model number
int nTorso = GetItemAppearance( oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO);
// Read 2DA for base AC
// Can also use "parts_chest" which returns it as a "float"
string sACBase = Get2DAString( "des_crft_appear", "BaseAC", nTorso);
// return base AC
return StringToInt( sACBase);
}
void main()
{
object oPC = GetPCItemLastUnequippedBy();
object oItem = GetPCItemLastUnequipped();
if (GetLevelByclass(class_TYPE_BARD, oPC) && GetBaseItemType(oItem) == BASE_ITEM_ARMOR) {
int iACVal = GetItemACBase(oItem);
if (iACVal > 0 && iACVal < 5)
IPRemoveMatchingItemProperties(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC), ITEM_PROPERTY_ARCANE_SPELL_FAILURE, DURATION_TYPE_PERMANENT);
}
}Looking forward to any reviews (assuming there are still people left playing NWN and checking these forums after the Rapture takes most of you).
Modifié par Thayan, 21 mai 2011 - 07:25 .
#14
Posté 21 mai 2011 - 03:01
My code is a bit messy as I have also few additional thing in code like a check for a new feat Battle Caster which improves this bards ability to medium armor as well as some VFXs when equipped etc. So if you want to see then tell me I can send either here or via PM.
#15
Posté 21 mai 2011 - 04:49
ShaDoOoW wrote...
I got it implemented in my working module. Im applying the lowered failure on the armor however. Why to mess with skin if you dont have to, right?
Granted that often there is more of a way to skin a cat, I like more the idea of the itemproperty on the skin/hide.
Doing so Thayan does not touch the very armor, which upon examination will not state extra properties that are not supposed to be seen by anybody.
Even if the above was unimportant, in any case to have an extra property on the very armor would lead to more trouble, hence more work to address it:
If the property is permanent, it will increase the GP value of the armor (think shopping), which is undesired.
If the property is temporary, instead, at some point you are going to reapply it -- meaning that you have to write some time-based code just to handle that.
-fox
#16
Posté 21 mai 2011 - 07:01
skins have more issue - ILR/ELC destroy skin at enter, equipping/unequipping, polymorph, horse system... I got my own skin system covered but if I do something, Im trying to avoid skin solution if possible due to reasons I provided.
#17
Posté 21 mai 2011 - 07:56
So after realizing I really did waste my Friday night on this thing, I put together this much simplified and cleaner version a littel bit ago that doesn't rely on .2da edits or toolset blueprints. Just plugin these scripts to your module OnEquip and OnUnequip and bards in your module will not suffer arcane spell failure while wearing light armor.
//mod_onequip_bard
#include "x2_inc_itemprop"
int GetItemACBase( object oItem)
{
if( !GetIsObjectValid( oItem) || (GetBaseItemType( oItem) != BASE_ITEM_ARMOR)) return -1;
int nTorso = GetItemAppearance( oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO);
string sACBase = Get2DAString( "des_crft_appear", "BaseAC", nTorso);
return StringToInt( sACBase);
}
void main()
{
object oPC = GetPCItemLastEquippedBy();
object oItem = GetPCItemLastEquipped();
if (GetLevelByclass(class_TYPE_BARD, oPC) && GetBaseItemType(oItem) == BASE_ITEM_ARMOR) { //Is this a bard equipping armor?
int iACVal = GetItemACBase(oItem);
if (iACVal > 0 && iACVal < 5) { //Only apply the Arcane Spellcasting Reduction if they equipped light armor
itemproperty ipAdd;
switch (iACVal) {
case 1: ipAdd = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_5_PERCENT);break;
case 2: ipAdd = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_10_PERCENT);break;
case 3: ipAdd = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_20_PERCENT);break;
case 4: ipAdd = ItemPropertyArcaneSpellFailure(IP_CONST_ARCANE_SPELL_FAILURE_MINUS_20_PERCENT);break;
default:return;
}
IPSafeAddItemProperty(oItem, ipAdd, 999999.9, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
DelayCommand(0.5, SendMessageToPC(oPC, "As a Bard you suffer no increase to Arcane Spell Failure wearing this light armor."));
}
}
}//mod_onunequ_bard
#include "x2_inc_itemprop"
int GetItemACBase( object oItem)
{
if( !GetIsObjectValid( oItem) || (GetBaseItemType( oItem) != BASE_ITEM_ARMOR)) return -1;
int nTorso = GetItemAppearance( oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO);
string sACBase = Get2DAString( "des_crft_appear", "BaseAC", nTorso);
return StringToInt( sACBase);
}
void main()
{
object oPC = GetPCItemLastUnequippedBy();
object oItem = GetPCItemLastUnequipped();
if (GetLevelByclass(class_TYPE_BARD, oPC) && GetBaseItemType(oItem) == BASE_ITEM_ARMOR) {
int iACVal = GetItemACBase(oItem);
if (iACVal > 0 && iACVal < 5)
IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_ARCANE_SPELL_FAILURE, DURATION_TYPE_TEMPORARY);
}
}
Modifié par Thayan, 21 mai 2011 - 08:04 .
#18
Posté 22 mai 2011 - 12:23
#19
Posté 22 mai 2011 - 01:56
#20
Posté 22 mai 2011 - 05:11
#21
Posté 23 mai 2011 - 06:59
You could use IPGetWeaponEnhancementBonus to get the AC bonus on the armor (if any) and subtract it from the total AC value of the armor:
#include "x2_inc_itemprop"
int GetItemACBase(object oItem)
{
if(!GetIsObjectValid(oItem) || (GetBaseItemType(oItem) != BASE_ITEM_ARMOR))
return -1;
int ac = GetItemACValue(oArmor) - IPGetWeaponEnhancementBonus(oArmor, ITEM_PROPERTY_AC_BONUS);
return ac;
}
Modifié par Khuzadrepa, 23 mai 2011 - 07:50 .
#22
Posté 23 mai 2011 - 07:51
#23
Posté 23 mai 2011 - 08:33
I think that way is also clever, but the one I posted is less code to write, which appeals to me.ShaDoOoW wrote...
or SetIdentified to FALSE and then check for cost of the item, this is the way I use
You're most likely right, though, it's probably a negligible difference as far as resources/speed.
Modifié par Khuzadrepa, 23 mai 2011 - 10:22 .
#24
Posté 24 mai 2011 - 02:52





Retour en haut







