Hi all,
I know I can put in the item property Cast Spell directly to the item. But I want to limit the spell ability based on the PC's level. So, I was thinking of using the unique power property, and scripting that. But looking at the functions, it seems they all would have to pre-target the target within the script. Any idea on how I can do this and still allow the player to target the object?
Item scripting to cast spell
Débuté par
Orion7486
, déc. 17 2010 03:26
#1
Posté 17 décembre 2010 - 03:26
#2
Posté 17 décembre 2010 - 12:13
You can use the Spell Hook to end or modify the spell casting.
If you don't know the hook system you can read this link, it is from NWN1 Wiki but it works fine for nwn2.
You can use the spell hook to change the casting from items after the target's selection
-------------------------
e.g.
//Code into Hook script
#inclede "x2_inc_switches"
void main()
{
object oPC = OBJECT_SELF; // the caster
object oItem = GetSpellCastItem(); // the item used to cast the spell
// you can add other variables by using the standard spell's functions
// GetSpellId, GetCasterLevel...
// now where you put your code to chance castinf from Item
if(oItem != OBJECT_INVALID){ // we have a valid Item, or you can use Tag or other condition
SetModuleOverrideSpellScriptFinished();
// this end the spell from the normal casting script
// other actions you want to do with this cast type....
}
....
}
----------------------------------------------------
The spellhook script run for every spell script, so if no conditionals are used it is applied to all spells before the normal effects.
If you don't know the hook system you can read this link, it is from NWN1 Wiki but it works fine for nwn2.
You can use the spell hook to change the casting from items after the target's selection
-------------------------
e.g.
//Code into Hook script
#inclede "x2_inc_switches"
void main()
{
object oPC = OBJECT_SELF; // the caster
object oItem = GetSpellCastItem(); // the item used to cast the spell
// you can add other variables by using the standard spell's functions
// GetSpellId, GetCasterLevel...
// now where you put your code to chance castinf from Item
if(oItem != OBJECT_INVALID){ // we have a valid Item, or you can use Tag or other condition
SetModuleOverrideSpellScriptFinished();
// this end the spell from the normal casting script
// other actions you want to do with this cast type....
}
....
}
----------------------------------------------------
The spellhook script run for every spell script, so if no conditionals are used it is applied to all spells before the normal effects.
#3
Posté 17 décembre 2010 - 02:53
I'll look into that if the way I'm thinking right now doesn't work.
Rather than scripting in Cast Spell properties based on level, I'm thinking of putting in all the properties into the item as normal, and then limiting access to those that are too high via script.
I don't know how to define it for each individual spell.
I'm trying to make a holy symbol with the Law domain bonuses in it. In that domain, bonus spells are Lionheart at 1st level, Hold Monster at 5th, and Mass Hold Person at 7th.
Now, here's what I got for the equipped event:
else if (nEvent ==X2_ITEM_EVENT_EQUIP)
{
oPC = GetPCItemLastEquippedBy();
oItem = GetPCItemLastEquipped();
int nLevel = GetLevelByclass(2, oPC);
itemproperty ipProp = GetFirstItemProperty(oItem);
if(nLevel < 7)
{
while (GetIsItemPropertyValid(ipProp))
{
if(GetItemPropertyType(ipProp) == ITEM_PROPERTY_CAST_SPELL)
{
}
}
}
}
Now, at this point, if the cleric level is under 7, I want to limit the Mass Hold Person, and keep Lionheart and Hold Monster. I can't figure out what parameter I could put in that defines specific spell for the Cast Spell property.
Any ideas?
Rather than scripting in Cast Spell properties based on level, I'm thinking of putting in all the properties into the item as normal, and then limiting access to those that are too high via script.
I don't know how to define it for each individual spell.
I'm trying to make a holy symbol with the Law domain bonuses in it. In that domain, bonus spells are Lionheart at 1st level, Hold Monster at 5th, and Mass Hold Person at 7th.
Now, here's what I got for the equipped event:
else if (nEvent ==X2_ITEM_EVENT_EQUIP)
{
oPC = GetPCItemLastEquippedBy();
oItem = GetPCItemLastEquipped();
int nLevel = GetLevelByclass(2, oPC);
itemproperty ipProp = GetFirstItemProperty(oItem);
if(nLevel < 7)
{
while (GetIsItemPropertyValid(ipProp))
{
if(GetItemPropertyType(ipProp) == ITEM_PROPERTY_CAST_SPELL)
{
}
}
}
}
Now, at this point, if the cleric level is under 7, I want to limit the Mass Hold Person, and keep Lionheart and Hold Monster. I can't figure out what parameter I could put in that defines specific spell for the Cast Spell property.
Any ideas?
#4
Posté 17 décembre 2010 - 06:34
Well, this is what I've come up with. For now, the item only has Lionheart, HoldMonster, and Mass Hold Person as properties. I have two problems with this script. One, it doesn't loop. Each time I equip it, it only removes one property. The way it is written, I would think it would remove all 3 properties. I've put the GetNext function in a couple of different lines with no effect.
The second problem is I still haven't figured out how to specify a certain spell property so only, say the Mass Hold Person property is removed, but the other two are kept.
else if (nEvent ==X2_ITEM_EVENT_EQUIP)
{
oPC = GetPCItemLastEquippedBy();
oItem = GetPCItemLastEquipped();
int nLevel = GetLevelByclass(2, oPC);
itemproperty ipProp = GetFirstItemProperty(oItem);
int iPropType = GetItemPropertyType(ipProp);
itemproperty ipSpell;
if(nLevel < 7)
{
while (GetIsItemPropertyValid(ipProp))
{
if(iPropType == ITEM_PROPERTY_CAST_SPELL)
{
RemoveItemProperty(oItem, ipProp);
//ipProp == GetNextItemProperty(oItem);
}
/*else
{
ipProp == GetNextItemProperty(oItem);
}*/
ipProp == GetNextItemProperty(oItem);
}
}
}
The second problem is I still haven't figured out how to specify a certain spell property so only, say the Mass Hold Person property is removed, but the other two are kept.
else if (nEvent ==X2_ITEM_EVENT_EQUIP)
{
oPC = GetPCItemLastEquippedBy();
oItem = GetPCItemLastEquipped();
int nLevel = GetLevelByclass(2, oPC);
itemproperty ipProp = GetFirstItemProperty(oItem);
int iPropType = GetItemPropertyType(ipProp);
itemproperty ipSpell;
if(nLevel < 7)
{
while (GetIsItemPropertyValid(ipProp))
{
if(iPropType == ITEM_PROPERTY_CAST_SPELL)
{
RemoveItemProperty(oItem, ipProp);
//ipProp == GetNextItemProperty(oItem);
}
/*else
{
ipProp == GetNextItemProperty(oItem);
}*/
ipProp == GetNextItemProperty(oItem);
}
}
}
#5
Posté 17 décembre 2010 - 06:51
You can use Tag scriptin in this way.
Create the Item with NO CAST SPELL Itemproperty, but with the correct description for players to examine (with the spells and the level required to cast them).
Now use two Tag Based Scripts:
i_<Item Tag>_aq
i_<Item Tag>_ua
The first script is utomatically run in onAquire event and the second in onUnAquire event o Item tagged <Item Tag>
---------------------- i_<Tag>_aq ------------------------------
void main(){
object oItem = OBJECT_SELF;
object oPlayer = GetLastAquiredBy();
int nLevel = GetLevelByclass(2,oPlayer);
// the three itemproperty you want to apply to object, use the correct values for spells and uses per day
itemproperty iprLionheart = ItemPropertyCastspell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
itemproperty iprHoldMonster = ItemPropertyCastSpell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
itemproperty iprMassHoldPerson = ItemPropertyCastSpell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
// now we can apply the property based on level
if(nLevel>=1) AddItemProperty(DURATION_TYPE_PERMANENT,iprLionHeart,oItem);
if(nLevel>=5) AddItemProperty(DURATION_TYPE_PERMANENT,iprHoldMonster);
if(nLevel>=7) AddItemProperty(DURATION_TYPE_PERMANENT,iprMassHoldPerson);
}
--------------------
Now we remove the properti with Un-Aquire event
--------- i_<tag>_ua --------------
void main(){
object oItem = OBJECT_SELF;
itemproperty iprProperty = GetFirstItemproperty(oItem);
int nType = GetItempropertyType(iprProperty);
while(GetIsItempropertyValid(iprProperty){
if(nType == ITEM_PROPERTY_CAST_SPELL) RemoveItemProperty(oItem,iprProperty);
iprProperty = GetNextItemProperty(oItem);
nType = GetItempropertyType(iprProperty);
} // end while
}
----------------
In this way we add to the object the desidered itemproperty based on PC's Level when the Item is Aquired, and remove all property when the item is Unaquired.
(I think there is no itemproperty to cast Lionheart, you should create it or change with other spell).
Create the Item with NO CAST SPELL Itemproperty, but with the correct description for players to examine (with the spells and the level required to cast them).
Now use two Tag Based Scripts:
i_<Item Tag>_aq
i_<Item Tag>_ua
The first script is utomatically run in onAquire event and the second in onUnAquire event o Item tagged <Item Tag>
---------------------- i_<Tag>_aq ------------------------------
void main(){
object oItem = OBJECT_SELF;
object oPlayer = GetLastAquiredBy();
int nLevel = GetLevelByclass(2,oPlayer);
// the three itemproperty you want to apply to object, use the correct values for spells and uses per day
itemproperty iprLionheart = ItemPropertyCastspell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
itemproperty iprHoldMonster = ItemPropertyCastSpell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
itemproperty iprMassHoldPerson = ItemPropertyCastSpell(IP_CONST_CASTSPELL_*,IP_CONST_CASTSPELL_NUMUSES_*);
// now we can apply the property based on level
if(nLevel>=1) AddItemProperty(DURATION_TYPE_PERMANENT,iprLionHeart,oItem);
if(nLevel>=5) AddItemProperty(DURATION_TYPE_PERMANENT,iprHoldMonster);
if(nLevel>=7) AddItemProperty(DURATION_TYPE_PERMANENT,iprMassHoldPerson);
}
--------------------
Now we remove the properti with Un-Aquire event
--------- i_<tag>_ua --------------
void main(){
object oItem = OBJECT_SELF;
itemproperty iprProperty = GetFirstItemproperty(oItem);
int nType = GetItempropertyType(iprProperty);
while(GetIsItempropertyValid(iprProperty){
if(nType == ITEM_PROPERTY_CAST_SPELL) RemoveItemProperty(oItem,iprProperty);
iprProperty = GetNextItemProperty(oItem);
nType = GetItempropertyType(iprProperty);
} // end while
}
----------------
In this way we add to the object the desidered itemproperty based on PC's Level when the Item is Aquired, and remove all property when the item is Unaquired.
(I think there is no itemproperty to cast Lionheart, you should create it or change with other spell).
#6
Posté 17 décembre 2010 - 09:08
I am using tag-based script, but I'm using the one where it's all tied into one script for each item.
Yes, what you have looks like it would work and is somewhat easier.
Though, there is no listing in the script assist for Lionheart constant, there is a listing for it in the iprp_spells 2da. I'll try using the row number the IP_CONST refers to and see if it works for Lionheart.
Thanks for the help.
Yes, what you have looks like it would work and is somewhat easier.
Though, there is no listing in the script assist for Lionheart constant, there is a listing for it in the iprp_spells 2da. I'll try using the row number the IP_CONST refers to and see if it works for Lionheart.
Thanks for the help.
#7
Posté 17 décembre 2010 - 09:44
If Lionheart has a row into iprp_spells.2da (when I wrote the reply I didn't make a control) it will works, just use the number, I used the same system for custom spells in PW.
#8
Posté 18 décembre 2010 - 01:42
The meat of the script is now working, thanks to you. I had to change AddItemProperty to IPSafeAddItemProperty. With AddItemProperty, if the 1 use/day was used, and then item was unequiped then equiped, I ended up with 2 of that property, one with 0 uses, and one with 1 use.
However, that brings up a small problem. As it is right now, a player can get around the # of uses/day by just unequiping/equiping the item for a full # of uses.
However, that brings up a small problem. As it is right now, a player can get around the # of uses/day by just unequiping/equiping the item for a full # of uses.
#9
Posté 18 décembre 2010 - 02:41
You could script the item to open up a dialogue, then use the dialogue to allow different spells to be cast depending on the level of the character.
#10
Posté 18 décembre 2010 - 03:43
Well, the spell availability works except for the 'cheat' of reequiping for the purposes of gaining daily use. And since this is supposed to model domain power within a holy symbol, this would often be used within combat, so dialogue wouldn't be an option. Thanks for the idea.





Retour en haut






