Flame Weapon for off-hand weapon

Forum for scripters of NWN material and third party applications.
Post Reply
Bruno Knotslinger
Ambassador: Greyhawk West
Posts: 61
Joined: Wed May 18, 2005 12:49 pm

Flame Weapon for off-hand weapon

Post by Bruno Knotslinger »

One of the things that annoys me about buffing (myself and others) is constantly having to tell them to put their off-hand weapon into main weapon slot so that I can cast Greater Magic Weapon and Flame Weapon on it. (Of course this applies to other spells as well, such as Darkfire, Magic Weapon, and Keen Weapon.)

So I set about modifying the code for flame weapon (as a start) as follows:

If the main weapon does not have flame weapon on it, add flame weapon to it.

If the main weapon already has flame weapon on it, then check the off-hand weapon. If it doesn't have the flame weapon effect, add it.

If both have flame weapon, then apply it to the main weapon.

Ideally, it would check the remaining time left on both and apply it to the weapon which would run out first, but I haven't yet found the function to return the duration left on a temporary effect (if there is one, please let me know). So that will explain why it is coded as it is when you take a look at it.

A couple of notes before I post the code. The original flame weapon works on natural weapons. I've removed that. Further, the original flame weapon would only work on the right or bite natural weapon and not the left natural weapon as that is excluded in the IPGetTargetedOrEquippedMeleeWeapon.

Anyway, on to the code. Please let me know if you see anything obviously wrong (or subtly wrong). Thanks in advance. (I hesitate to mention it as it should be obvious, but this is the spellhook script.)

Code: Select all

#include "nw_i0_spells"
#include "x2_i0_spells"
#include "x2_inc_switches"

void jsAddFlamingEffectToWeapon(object oTarget, float fDuration, int nCasterLevel)
{
   // If the spell is cast again, any previous itemproperties matching are removed.
   IPSafeAddItemProperty(oTarget, ItemPropertyOnHitCastSpell(124,nCasterLevel), fDuration, X2_IP_ADDPROP_POLICY_REPLACE_EXISTING);
   IPSafeAddItemProperty(oTarget, ItemPropertyVisualEffect(ITEM_VISUAL_FIRE), fDuration,X2_IP_ADDPROP_POLICY_REPLACE_EXISTING,FALSE,TRUE);
   return;
}

object IPGetTargetedOrEquippedMeleeWeaponEffect(itemproperty ip_toadd)
{
  int durr = -1;
  int durl = -1;
  object oTarget = GetSpellTargetObject();
  if(GetIsObjectValid(oTarget) && GetObjectType(oTarget) == OBJECT_TYPE_ITEM)
  {
    if (IPGetIsMeleeWeapon(oTarget))
    {
        return oTarget;
    }
    else
    {
        return OBJECT_INVALID;
    }

  }

  // Check for wielded weapons first.

  object oWeaponr = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oTarget);
  object oWeaponl = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oTarget);

  if ((GetIsObjectValid(oWeaponr) && IPGetIsMeleeWeapon(oWeaponr)) ||
      (GetIsObjectValid(oWeaponl) && IPGetIsMeleeWeapon(oWeaponl)))
  {
    // It will be added to one of these weapons.

    if (GetIsObjectValid(oWeaponr) && IPGetIsMeleeWeapon(oWeaponr))
    {
      // Get the duration of the effect for right weapon.
      if (IPGetItemHasProperty(oWeaponr,ip_toadd,DURATION_TYPE_TEMPORARY))
      {
        durr = 1;
      }
      else
      {
        durr = 0;
      }
    }
    if (GetIsObjectValid(oWeaponl) && IPGetIsMeleeWeapon(oWeaponl))
    {
      // Get the duration of the effect for left weapon.
      if (IPGetItemHasProperty(oWeaponl,ip_toadd,DURATION_TYPE_TEMPORARY))
      {
        durl = 1;
      }
      else
      {
        durl = 0;
      }
    }

    if (durr == -1)
    {
      return oWeaponl;
    }
    if (durl == -1)
    {
      return oWeaponr;
    }
    if (durr <= durl)
    {
      return oWeaponr;
    }
    else
    {
      return oWeaponl;
    }
  }

  return OBJECT_INVALID;
}


void main()
{
  int nSpell=GetSpellId();
  switch(nSpell)
  {
    case SPELL_FLAME_WEAPON:
      effect eVis = EffectVisualEffect(VFX_IMP_PULSE_FIRE);
      effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
      int nDuration = 2 * GetCasterLevel(OBJECT_SELF);
      int nMetaMagic = GetMetaMagicFeat();
      int nCasterLvl = GetCasterLevel(OBJECT_SELF);

      //Limit nCasterLvl to 10, so it max out at +10 to the damage.
      if(nCasterLvl > 10)
      {
          nCasterLvl = 10;
      }

      if (nMetaMagic == METAMAGIC_EXTEND)
      {
          nDuration = nDuration * 2; //Duration is +100%
      }

     object oMyWeapon   =  IPGetTargetedOrEquippedMeleeWeaponEffect(ItemPropertyOnHitCastSpell(124,nCasterLvl));

     if(GetIsObjectValid(oMyWeapon) )
     {
          SignalEvent(GetItemPossessor(oMyWeapon), EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE));

          if (nDuration>0)
          {
              // haaaack: store caster level on item for the on hit spell to work properly
              ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, GetItemPossessor(oMyWeapon));
              ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, GetItemPossessor(oMyWeapon), TurnsToSeconds(nDuration));
              jsAddFlamingEffectToWeapon(oMyWeapon, TurnsToSeconds(nDuration),nCasterLvl);
          }
      }
       else
      {
             FloatingTextStrRefOnCreature(83615, OBJECT_SELF);
      }
      SetModuleOverrideSpellScriptFinished();
    break;
  }
}
Bruno Knotslinger
Ambassador: Greyhawk West
Posts: 61
Joined: Wed May 18, 2005 12:49 pm

Post by Bruno Knotslinger »

Oops... variable declarations moved outside of the case.
Post Reply