[NWN] How To: Make a Potion of Heroism

LightPhoenix

First Post
Alrighty, this one is a bit more difficult, but nothing that anyone shouldn't be able to handle.

First, a few concepts that we need to go over. If you open up Edit -> Module Properties and choose the Events tab, you'll see a bunch of events that can have scripts attached to them. Notably, you should see three entries already filled in - OnPlayerDeath, OnPlayerDying, and OnPlayerRespawn. These obviously control how death and spawning work in your game. We're interested in a different one - OnActivateItem. The script here is called whenever an item is activated. As you might guess, we're going to change that.

Another fundamental part of stuff in NWN is the "effect" type. They are initialized just like ints, floats, strings, and objects. For instance: effect eDamage; Simple as that. There are a number of things we can do with these - deal damage, show visial effects... you're basically limited only by what the game lets you do. Of specific note is that we can increase AC, skills, and saves.

Before we can script anything, you need to make the item. Make a potion, call it Potion of Heroism. In the Properties tab, the only effect you want it to have is "Unique Effect - Self only". You might want to put in a price adjustment too, since there's no price attached to this property.

So let's look at some code. Create a new script, name it whatever you like. In the OnActivateItem box from before, put the name of your script. This way, we'll be able to have items with custom effects in the game.

Here's my Potion of Heroism:

Code:
void main()
{
    object oActivatedItem = GetItemActivated();

    //
    // Activated Item: Potion of Heroism
    // Effect: Target creature gains +2 to attacks, saves, and skill checks for 1 hour.
    //
    if (oActivatedItem == GetObjectByTag("PotionofHeroism"))
    {
        //Declare major variables
        int nBonus = 2;
        float nDur = 3600.0;
        object oTarget = GetItemActivator();
        // Setup the instant visual effect
        effect eVis = EffectVisualEffect(VFX_IMP_SUPER_HEROISM);
        // Setup the Heroism bonuses
        effect eAttack = EffectAttackIncrease(nBonus);
        effect eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, nBonus, SAVING_THROW_TYPE_ALL);
        effect eSkill = EffectSkillIncrease(SKILL_ALL_SKILLS, nBonus);
        effect eLink = EffectLinkEffects(eAttack, eSave);
        eLink = EffectLinkEffects(eLink, eSkill);
        //Apply the VFX impact and effects
        ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, nDur);
    }
}

Oof, quite a handful, but not nearly as bad as it might seem. We'll start from the top.

Code:
object oActivatedItem = GetItemActivated();

if (oActivatedItem == GetObjectByTag("PotionofHeroism"))
{
     // Stuff goes here
}

THE most important line. This gets the tag of the item that has been activated. We use this in the if statement to check what has been activated, and perform code based on that.

Code:
//Declare major variables
int nBonus = 2;
float nDur = 3600.0;
object oTarget = GetItemActivator();

This section just declares variable. They're put up top to make changing them easier. It's nothing you have to do, but it avoids having to go through lines of code searching for one number. Note that nDur is in seconds - this potion lasts one hour. Also, no the GetItemActivator() function - this sets the target as the imbiber. There's also GetItemActivatedTarget() to get other targets, but we don't need that here.

Code:
// Setup the instant visual effect
effect eVis = EffectVisualEffect(VFX_IMP_SUPER_HEROISM);

// Setup the Heroism bonuses
effect eAttack = EffectAttackIncrease(nBonus);
effect eSave = EffectSavingThrowIncrease(SAVING_THROW_ALL, nBonus, SAVING_THROW_TYPE_ALL);
effect eSkill = EffectSkillIncrease(SKILL_ALL_SKILLS, nBonus);
effect eLink = EffectLinkEffects(eAttack, eSave);
eLink = EffectLinkEffects(eLink, eSkill);

The meaty section. As you can see, there's a lot of "Effect" functions. The first sets up a visual effect, important but nothing special. The next group sets up the bonuses. As a note, for EffectSavingThrowIncrease - the first constant (SAVING_THROW_ALL) tells it to apply the save to Fort, Ref, and Will. The second (SAVING_THROW_TYPE_ALL) tells it to apply to all types of saving throws - vs. Poison, vs. Fire, whatever.

Important is the function EffectLinkEffects(). We need this because the functions which apply effects only take one effect as a parameter. This function will take two effects and link them together. You can not link visual and statistical effects, as far as I know. In the code, we link the three bonuses together so they're all called as one.

Code:
//Apply the VFX impact and effects
ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, nDur);

The home stretch - this just applies the effects. Note the same function, but different numbers of parameters. Instant effects obviously don't need a duration, but temporary ones do. This sets off the visual effect, and applies the bonus for one hour.

I'd be more than happy to answer any questions or to give another example is people want one.
 
Last edited:

log in or register to remove this ad

LightPhoenix, this stuff is awsome! Not nessecarily (i think i spelled that wrong) the potion itself, but the whole tuturial you gave on how to make it. Thanks! This stuff is so much appreciated, i really want to see more. This is the way i learn stuff, see how it's implemented and play with it untill i fully understand what everything does.

@Morrus
This really belongs at the NWN@ENWORLD site under the header tuturials. Please make it so! (ack! why the ST line, why, oh why ;-)
 

Thanks!

I wish I could take full credit, I got this by posting at the official boards (nwn.bioware.com), but all the guy had posted was a bunch of code, so I had to go through and try to understand everything myself. I thought I'd share it, with a little more explanation.
 

This looks great from what I can see of it. Maybee its just me or somthing happened when this was moved, but I can see all of the discriptive text, but none of the code???
 


Addendum to post

Okay, so apparently there's some goofy bug where if you compare by object (as I did above) you won't be able to use more than one potion. So instead you have to compare by tags. This doesn't change the code that much - updated code is below.

Code:
void main()
{
    object oActivatedItem = GetItemActivated();
    string sTag = GetTag(oActivatedItem);

    //
    // Activated Item: Potion of Heroism
    // Effect: Target creature gains +2 to attacks, saves, and skill checks for 1 hour.
    //
    if (sTag == "PotionofHeroism")
    {
          Yadda, yadda, yadda...
    }
}
 
Last edited:


Remove ads

Top