Code: Select all
/*
Custom object effects for NWN - Version 0.1 beta
Made By KORRIGAN
The script uses the tag of items with unique powers as a command line.
SEE EXAMPLE BELOW FOR MORE HELP
the tag format is following :
FX_<type>_...parameters...
- type : Actually, the type of effect can only be "DR", which applies a damage reduction effect on the PC.
Then, the parameters are following :
FX_DR_<dmg_type>_<amount>_<limit>_<duration>_<forbidden class 1>_<forbidden class 2>_ ...
- dmg_type can be :
Fi(FIRE),Co(COLD),Ac(ACID),El(ELECTRICAL),So(SONIC),Sl(SLASHING),Pi(PIERCING),Bl(BLUGEONING)
- amount is the quantity of damage that will be negated.
- limit is the quantity of damage that can be absobed before the protection fades. 0=infinite.
- duration is the max duration in seconds the protection will last.
- forbidden classes are the PC classes that CANNOT use the item.
Even multiclassed PCs will no longer be able to take 1 level of a class just to use some items.
Forbidden classes can be :
Ba (Barbarian)
Bd (Bard)
Cl (Cleric)
Dr (Druid)
Fi (Fighter)
Mo (Monk)
Pa (Paladin)
Ra (Ranger)
Ro (Rogue)
So (Sorcerer)
Wi (Wizard)
WHY THE HELL ARE YOU DOING THAT ???
Permanent damage reduction items are totally overpowered in NWN.
But if you remove them all, it makes spellcasters godlike compared to pure non spellcasters.
I also wanted to introduce a system that allowed to avoid people taking 1 level of a class simply for the sake of using certain items.
EXAMPLE :
You want to make a damage reduction amulet that :
- Is usable 3 times a day.
- Negates 10 points of SLASHING damage.
- Effect lasts 1 minute (real time).
- No limitation to the damage absorbed.
- Is usable only by classes that don't have Wizard, Cleric, Druid or Sorcerer levels.
- Is usable only on self.
1) Simply put this script in the onactivate script of your module.
2) Create an amulet using the item wizard. Make it's only feature "Unique power self only 3 uses/day".
3) Edit the tag of the amulet and make it :
FX_DR_Sl_10_0_60_Wi_Cl_Dr_So
FX = this is a custom effect
DR = Damage Reduction
Sl = Slashing
10 = 10 damage is negated
0 = unlimited damage is absorbed
60 = lasts 60 seconds real time
Wi = not usable by Wizards.
Cl = not usable by Clerics.
Dr = not usable by Druids.
So = not usable by Sorcerers.
You're done =)
PS : Of course, you can set the usual usage restrictions using the regular way through the toolset.
*/
string ParseTag(string tag,int entry)
{
string result="";
string temp="";
int start=0;
int end=0;
while (entry>0)
{
temp=GetSubString(tag,start,1);
if (temp=="")
return ""; // too far in the line, dumbass =P
if (temp=="_")
{
entry--;
}
start++;
if (entry==0)
break;
}
end=start;
do
{
end++;
temp=GetSubString(tag,end,1);
} while ((temp!="_") && (temp!=""));
if (end>start+1)
{
result=GetSubString(tag,start,end-start);
}
return result;
}
int ParseTagInt(string tag,int entry)
{
int result=0;
string arg;
arg=ParseTag(tag,entry);
if (arg!="")
result=StringToInt(arg);
return result;
}
float ParseTagFloat(string tag,int entry)
{
float result=0.0;
string arg;
arg=ParseTag(tag,entry);
if (arg!="")
result=StringToFloat(arg);
return result;
}
// number is the first argument of the command starting the forbidden classes list
int IsClassForbidden(object activator, string tag, int number)
{
string arg;
arg=ParseTag(tag,number);
while (arg!="")
{
if (arg=="Ba")
{
if (GetLevelByClass(CLASS_TYPE_BARBARIAN,activator)>0)
return TRUE;
}
else
if (arg=="Bd")
{
if (GetLevelByClass(CLASS_TYPE_BARD,activator)>0)
return TRUE;
}
else
if (arg=="Cl")
{
if (GetLevelByClass(CLASS_TYPE_CLERIC,activator)>0)
return TRUE;
}
else
if (arg=="Dr")
{
if (GetLevelByClass(CLASS_TYPE_DRUID,activator)>0)
return TRUE;
}
else
if (arg=="Fi")
{
if (GetLevelByClass(CLASS_TYPE_FIGHTER,activator)>0)
return TRUE;
}
else
if (arg=="Mo")
{
if (GetLevelByClass(CLASS_TYPE_MONK,activator)>0)
return TRUE;
}
else
if (arg=="Pa")
{
if (GetLevelByClass(CLASS_TYPE_PALADIN,activator)>0)
return TRUE;
}
else
if (arg=="Ra")
{
if (GetLevelByClass(CLASS_TYPE_RANGER,activator)>0)
return TRUE;
}
else
if (arg=="Ro")
{
if (GetLevelByClass(CLASS_TYPE_ROGUE,activator)>0)
return TRUE;
}
else
if (arg=="So")
{
if (GetLevelByClass(CLASS_TYPE_SORCERER,activator)>0)
return TRUE;
}
else
if (arg=="Wi")
{
if (GetLevelByClass(CLASS_TYPE_WIZARD,activator)>0)
return TRUE;
}
number++;
arg=ParseTag(tag,number);
}
return FALSE;
}
void ApplyDamageReduction(object activator,string tag)
{
if (IsClassForbidden(activator,tag,6))
{
SendMessageToPC(activator,"This effect cannot be used on this class");
}
else
{
int type;
string arg;
effect effex;
int vfx1;
int vfx2;
int amount;
int limit;
float duration;
arg=ParseTag(tag,2);
if (arg=="Fi")
{
type=DAMAGE_TYPE_FIRE;
vfx1=VFX_IMP_HEAD_FIRE;
vfx2=VFX_DUR_PROTECTION_ELEMENTS;
}
if (arg=="Co")
{
type=DAMAGE_TYPE_COLD;
vfx1=VFX_IMP_HEAD_COLD;
vfx2=VFX_DUR_PROTECTION_ELEMENTS;
}
if (arg=="Ac")
{
type=DAMAGE_TYPE_ACID;
vfx1=VFX_IMP_HEAD_ACID;
vfx2=VFX_DUR_PROTECTION_ELEMENTS;
}
if (arg=="El")
{
type=DAMAGE_TYPE_ELECTRICAL;
vfx1=VFX_IMP_HEAD_ELECTRICITY;
vfx2=VFX_DUR_PROTECTION_ELEMENTS;
}
if (arg=="So")
{
type=DAMAGE_TYPE_SONIC;
vfx1=VFX_IMP_HEAD_SONIC;
vfx2=VFX_DUR_PROTECTION_ELEMENTS;
}
if (arg=="Pi")
{
type=DAMAGE_TYPE_PIERCING;
vfx1=VFX_IMP_HEAD_ODD;
vfx2=VFX_DUR_PROT_STONESKIN;
}
if (arg=="Sl")
{
type=DAMAGE_TYPE_SLASHING;
vfx1=VFX_IMP_HEAD_ODD;
vfx2=VFX_DUR_PROT_STONESKIN;
}
if (arg=="Bl")
{
type=DAMAGE_TYPE_BLUDGEONING;
vfx1=VFX_IMP_HEAD_ODD;
vfx2=VFX_DUR_PROT_STONESKIN;
}
amount=ParseTagInt(tag,3);
limit=ParseTagInt(tag,4);
duration=ParseTagFloat(tag,5);
effex=EffectLinkEffects(
EffectVisualEffect(vfx1,FALSE),
EffectDamageResistance(type,amount,limit));
effex=EffectLinkEffects(
EffectVisualEffect(vfx2,FALSE),
effex);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,effex,activator,duration);
}
}
void ApplyCustomEffect(object activator,string tag)
{
if (ParseTag(tag,1)=="DR")
ApplyDamageReduction(activator,tag);
}
void main()
{
object item;
object activator;
string tag;
item=GetItemActivated();
activator=GetItemActivatedTarget();
tag=GetTag(item);
if (ParseTag(tag,0)=="FX")
{
ApplyCustomEffect(activator,tag);
return;
}
// ... do your usual itemactivation stuff here
}