Author Topic: Are you allowed to have more than one event in a tag based script?  (Read 673 times)

Legacy_Imperator

  • Full Member
  • ***
  • Posts: 128
  • Karma: +0/-0


               

Can I have two or even three events in a single tag based script for an item? I feel like this is way easier than inserting the necessary events into each module event separately.. just have them all here in this one script for this one item. Unfortunately when a player unequips the item the penalty isn't removed.


 


#include "x2_inc_switches"


void main()

{

    int nEvent = GetUserDefinedItemEventNumber();

    object oSelf;

    object oItem;


   SendMessageToPC(GetFirstPC(),IntToString(nEvent));



        if (nEvent ==X2_ITEM_EVENT_EQUIP)

    {

        oSelf = GetPCItemLastEquippedBy();

        oItem = GetPCItemLastEquipped();

int eHealSkill = GetSkillRank(SKILL_HEAL, oSelf, FALSE);

effect dHeal = EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );

ApplyEffectToObject(DURATION_TYPE_PERMANENT, dHeal, oSelf);

    }



    if (nEvent ==X2_ITEM_EVENT_UNEQUIP)

    {

        oSelf  = GetPCItemLastUnequippedBy();

        oItem  = GetPCItemLastUnequipped();

        int eHealSkill = GetSkillRank(SKILL_HEAL, oSelf, FALSE);

        effect dHeal = EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );

        RemoveEffect(oSelf, dHeal);

    }



}


 


Also wondering how I can make the penalty for heal skill unrestorable :3 ...



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Are you allowed to have more than one event in a tag based script?
« Reply #1 on: April 19, 2016, 10:19:19 am »


               The problem is with your unequip code. The Lexicon explains how to use RemoveEffect in that situation.

To prevent the effect being restored by rest etc

effect dHeal = EffectSupernaturalEffect(EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 ));

               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Are you allowed to have more than one event in a tag based script?
« Reply #2 on: April 19, 2016, 02:31:03 pm »


               


Can I have two or even three events in a single tag based script for an item? I feel like this is way easier than inserting the necessary events into each module event separately.. just have them all here in this one script for this one item. Unfortunately when a player unequips the item the penalty isn't removed.


 


#include "x2_inc_switches"


void main()

{

    int nEvent = GetUserDefinedItemEventNumber();

    object oSelf;

    object oItem;


   SendMessageToPC(GetFirstPC(),IntToString(nEvent));



        if (nEvent ==X2_ITEM_EVENT_EQUIP)

    {

        oSelf = GetPCItemLastEquippedBy();

        oItem = GetPCItemLastEquipped();

int eHealSkill = GetSkillRank(SKILL_HEAL, oSelf, FALSE);

effect dHeal = EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );

ApplyEffectToObject(DURATION_TYPE_PERMANENT, dHeal, oSelf);

    }



    if (nEvent ==X2_ITEM_EVENT_UNEQUIP)

    {

        oSelf  = GetPCItemLastUnequippedBy();

        oItem  = GetPCItemLastUnequipped();

        int eHealSkill = GetSkillRank(SKILL_HEAL, oSelf, FALSE);

        effect dHeal = EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );

        RemoveEffect(oSelf, dHeal);

    }



}


 


Also wondering how I can make the penalty for heal skill unrestorable :3 ...




 


Everything in nwn has its own unique ID


You cannot really see this, through NWScript, but it does exist.


You can use ObjectToString to see it for objects, but it doesn't end just there, effects have their own unique IDs too.


They are instanced classes which get created when you call one of the Effect functions.


 


So when you are doing


 


 



effect dHeal = EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );
        RemoveEffect(oSelf, dHeal);


 



 


This does not remove the effect from the player, because you are attempting to remove an effect that has not been applied to the player in the first place.


 


dHeal has been created by EffectSkillDecrease(SKILL_HEAL, eHealSkill/2 );


but has not been applied to any creature, so the RemoveEffect call is redundant.


 


In order to remove the effect applied in the Equip event, you need to loop through the characters effects, and find an effect that matches the type and subtype you are looking for.



 
effect e = GetFirstEffect(oPC);
object oEffectCreator = GetMySpecialCreator();
while(GetIsEffectValid(e)){
 
          int iType = GetEffectType(e);
          int iSubType = GetEffectSubType(e);
          object oCreator = GetEffectCreator(e);
          if(iType == EFFECT_TYPE_SKILL_DECREASE && iSubType == SUBTYPE_SUPERNATURAL &&  oCreator == oEffectCreator) {
                RemoveEffect(oPC,e);
          }
          
    e = GetNextEffect(oPC);
}
 

You are limited in the amount of information you can get from an existing effect.


Eg: Where it originally came from, eg: Was it created when you equipped the item, or was it created by a spell someone cast on you.


 


In order to differentiate between these, I recommend you create a placeable, or NPC, that applies the 'special' effects for you.


Then you can tell if these are the effects that you want to have removed on unequip.


 


 


 
object MyCreatorObject(){
 
 return GetObjectByTag("my_effect_creator");
 
}
 
effect GetEffectFromID(int EffectID, int Value1, int Value2)
{
   effect iEffect;
   switch(EffectID)
   {
      case EFFECT_TYPE_ARCANE_SPELL_FAILURE: iEffect = EffectSpellFailure(Value1, Value2); break;
      case EFFECT_TYPE_BLINDNESS: iEffect = EffectBlindness(); break;
      case EFFECT_TYPE_CHARMED: iEffect = EffectCharmed();break;
      case EFFECT_TYPE_CONCEALMENT: iEffect = EffectConcealment(Value1, Value2); break;
      case EFFECT_TYPE_CONFUSED: iEffect = EffectConfused(); break;
      case EFFECT_TYPE_CUTSCENEGHOST: iEffect = EffectCutsceneGhost(); break;
      case EFFECT_TYPE_HASTE: iEffect = EffectHaste(); break;
      case EFFECT_TYPE_IMMUNITY: iEffect = EffectImmunity(Value1); break;
      case EFFECT_TYPE_IMPROVEDINVISIBILITY: iEffect = EffectInvisibility(INVISIBILITY_TYPE_IMPROVED); break;
      case EFFECT_TYPE_INVISIBILITY: iEffect = EffectInvisibility(INVISIBILITY_TYPE_NORMAL); break;
      case EFFECT_TYPE_MISS_CHANCE: iEffect = EffectMissChance(Value1, Value2); break;
      case EFFECT_TYPE_MOVEMENT_SPEED_DECREASE: iEffect = EffectMovementSpeedDecrease(Value1); break;
      case EFFECT_TYPE_MOVEMENT_SPEED_INCREASE: iEffect = EffectMovementSpeedIncrease(Value2); break;
      case EFFECT_TYPE_POLYMORPH: iEffect = EffectPolymorph(Value1, Value2);   break;
      case EFFECT_TYPE_REGENERATE: iEffect = EffectRegenerate(Value1, IntToFloat(Value2)); break;
      case EFFECT_TYPE_SANCTUARY: iEffect = EffectSanctuary(Value1); break;
      case EFFECT_TYPE_SLOW: iEffect = EffectSlow();break;
      case EFFECT_TYPE_TEMPORARY_HITPOINTS: iEffect = EffectTemporaryHitpoints(Value1); break;
      case EFFECT_TYPE_TRUESEEING: iEffect = EffectTrueSeeing(); break;
      case EFFECT_TYPE_ULTRAVISION: EffectUltravision(); break;
      case EFFECT_TYPE_VISUALEFFECT: iEffect = EffectVisualEffect(Value1, Value2); break;
      case EFFECT_TYPE_DAMAGE_IMMUNITY_INCREASE: iEffect = EffectDamageImmunityIncrease(Value1, Value2); break;
      case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE: iEffect = EffectDamageImmunityDecrease(Value1, Value2); break;
      default: iEffect; break;
  }
  return iEffect;
}
 
 
//Note- Effects need to be 'created' by the creature, in order to have that creature as the creator.
//Who applies it is irrelevant.
void ApplyEffectFromCreator(object o, int effectType, int EffectNumber, int EffectNumber2, int durationType, float durationAmount){
        effect e = GetEffectFromID(effectType, EffectNumber, EffectNumber2);
        ApplyEffectToObject(durationType,e,o,durationAmount);
}
 
 
void Test(){
 
        object oPC = GetFirstPC();
        AssignCommand(MyCreatorObject(),ApplyEffectFromCreator(oPC, EFFECT_TYPE_SKILL_DECREASE, 10, 0, DURATION_TYPE_PERMANENT,0.00f));
 
}
 
 

 


This is pretty rough, but the idea is that you have to assign the effect creation and application, to another object, so that object gets marked as the creator.


Then when you do the removal, you can then check to see if that object was the creator of the effect.


If so - remove it.


If not, leave it.


               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Are you allowed to have more than one event in a tag based script?
« Reply #3 on: April 19, 2016, 06:05:00 pm »


               

Yes you can have all item events coded for in a single script. Here is an example of one of my scripts that has all defined.


 


In addiition you can include code before the event check that will run every time the script is called, as I have done in this script. Have a look. You'll see I use the "ADJUSTING" local check to create a sort of pseudo event I can trigger by setting the vatriable then running an ExecuteScript command. on the item.



/*::////////////////////////////////////////////////////////////////////////////
//:: Name: KMdS PNP Hard Core Rule Set 1.0
//:: System: KMdS AD&D 2nd ed Armor vs Weapon Type AC Modifiers
//:: FileName Armor
//:: Copyright (c) 2004 Michael Careaga
//::////////////////////////////////////////////////////////////////////////////
 
    The script is tag based script for armors to implement the D&D 2nd ed
    weapon type vs armor ac modifiers.  When creating any armor for this system
    the armors ttag must be "ARMOR" and the resref must be contain on of the
    following names...
 
    paddedarmor
    leatherarmor
    hidearmor
    studdedleather
    scalemail
    chainshirt
    chainmail
    breastplate
    splintmail
    bandedmail
    platemail       (2nd ed equivalent to 3rd ed half plate)
    fieldplate      (2nd ed equivalent to 3rd ed full plate)
    fullplate       (3rd ed has no equivalent other than +1 full plate)
 
    See inc_armor_system.nss for more info on all scripts in theHC Armor System
    package.
 
//::////////////////////////////////////////////////////////////////////////////
//:: Created By: Kilr Mik d Spik
//:: Created On: 12/18/2005
//:://////////////////////////////////////////////////////////////////////////*/
 
//  ----------------------------------------------------------------------------
//  LIBRARIES
//  ----------------------------------------------------------------------------
 
// BW library
#include "x2_inc_itemprop"
#include "x2_inc_switches"
 
// Custom library
#include "armor_system_inc"
 
//  ----------------------------------------------------------------------------
//  MAIN
//  ----------------------------------------------------------------------------
 
void main()
{
    int nEvent =GetUserDefinedItemEventNumber();
    object oPC;
    object oItem;
 
//   SendMessageToPC(GetFirstPC(),IntToString(nEvent));
 
    //* This code runs when a PC or DM enters a trigger that resets
    //* the weapon type vs. armor modifiers on a piece of armor.
    if (GetLocalInt(OBJECT_SELF,"ADJUSTING"))
    {
        oItem  = OBJECT_SELF;
 
        int nACBonus = ACBonus(oItem);
 
        //Get the first itemproperty on the helmet
        itemproperty ipLoop=GetFirstItemProperty(oItem);
 
        //Loop for as long as the ipLoop variable is valid
        while (GetIsItemPropertyValid(ipLoop))
        {
            //If ipLoop is a true seeing property, remove it
            if ((GetItemPropertyType(ipLoop)==ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE)||
                (GetItemPropertyType(ipLoop)==ITEM_PROPERTY_DAMAGE_VULNERABILITY))
                    RemoveItemProperty(oItem, ipLoop);
            else if (GetItemPropertyType(ipLoop)==ITEM_PROPERTY_AC_BONUS){
                int nACBonusCheck = GetItemPropertyCostTableValue(ipLoop);
                if (nACBonusCheck > nACBonus)
                    nACBonus = nACBonusCheck;
            }
            //Next itemproperty on the list...
            ipLoop=GetNextItemProperty(oItem);
        }
 
        int bHasMageArmorEffect = GetHasSpellEffect(SPELL_MAGE_ARMOR, GetItemPossessor(OBJECT_SELF));
 
        if (nACBonus < 1 && bHasMageArmorEffect && GetLocalInt(oItem, "EQUIPPED"))
            nACBonus = 1;
 
        struct armor stArmor = GetArmorStructById(oItem);
 
        itemproperty ipWepTypevsArmorTypeMod;
 
        if(stArmor.nSlashingACBonus){
            ipWepTypevsArmorTypeMod =
              ItemPropertyACBonusVsDmgType(IP_CONST_DAMAGETYPE_SLASHING, stArmor.nSlashingACBonus+nACBonus);
            IPSafeAddItemProperty(oItem,ipWepTypevsArmorTypeMod);
        }
        if(stArmor.nPiercingACBonus){
            ipWepTypevsArmorTypeMod =
              ItemPropertyACBonusVsDmgType(IP_CONST_DAMAGETYPE_PIERCING, stArmor.nPiercingACBonus+nACBonus);
            IPSafeAddItemProperty(oItem,ipWepTypevsArmorTypeMod);
        }
        if(stArmor.nBludgeoningACBonus){
            ipWepTypevsArmorTypeMod =
              ItemPropertyACBonusVsDmgType(IP_CONST_DAMAGETYPE_BLUDGEONING, stArmor.nBludgeoningACBonus+nACBonus);
            IPSafeAddItemProperty(oItem,ipWepTypevsArmorTypeMod);
        }
        if(stArmor.bVulnerableToPierce){
            ipWepTypevsArmorTypeMod =
                ItemPropertyDamageVulnerability(stArmor.nPConstant, stArmor.nPVulnerability);
            IPSafeAddItemProperty(oItem,ipWepTypevsArmorTypeMod);
        }
        if(stArmor.bVulnerableToBludgeon){
            ipWepTypevsArmorTypeMod =
                ItemPropertyDamageVulnerability(stArmor.nBConstant, stArmor.nBVulnerability);
            IPSafeAddItemProperty(oItem,ipWepTypevsArmorTypeMod);
        }
        SetLocalInt(oItem,"ADJUSTING",0);
    }
 
    // * This code runs when the item has the OnHitCastSpell: Unique power property
    // * and it hits a target(weapon) or is being hit (armor)
    // * Note that this event fires for non PC creatures as well.
    else if (nEvent ==X2_ITEM_EVENT_ONHITCAST)
    {
        oItem  =  GetSpellCastItem();                  // The item casting triggering this spellscript
        object oSpellOrigin = OBJECT_SELF ;
        object oSpellTarget = GetSpellTargetObject();
        oPC = OBJECT_SELF;
 
    }
 
    // * This code runs when the Unique Power property of the item is used
    // * Note that this event fires PCs only
    else if (nEvent ==  X2_ITEM_EVENT_ACTIVATE)
    {
 
        oPC   = GetItemActivator();
        oItem = GetItemActivated();
        object oPlayerskin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
 
        if(FindSubString(GetStringUpperCase(GetName(oItem)), "MAGES") > -1)
        {
            itemproperty ipProperty = ItemPropertyBonusFeat(IP_CONST_FEAT_ARMOR_PROF_HEAVY);
            IPSafeAddItemProperty(oPlayerskin, ipProperty, 6.0f);
            AssignCommand(oPC, ActionEquipItem(oItem, INVENTORY_SLOT_CHEST));
        }
    }
 
    // * This code runs when the item is equipped
    // * Note that this event fires PCs only
    else if (nEvent ==X2_ITEM_EVENT_EQUIP)
    {
 
        oPC = GetPCItemLastEquippedBy();
        oItem = GetPCItemLastEquipped();
        int bIsMetalOverride = GetLocalInt(oItem, "IS_NOT_METAL");
        struct armor stArmor = GetArmorStructById(oItem);
 
        if(stArmor.bIsMetal && !bIsMetalOverride && GetIsDruid(oPC) && !GetIsDM(oPC)){
            if(GetStringLowerCase(GetDeity(oPC))!="mielikki"){
                SendMessageToPC(oPC,Colorize("r","Druids who don metal armor loose their spellcasting ability, "+
                  "as per PHB page 34, while wearing the armor and for 24 hours after unequiping it."));
                SetDruidHasEquippedMetalArmor(oPC);
            }
            else if(stArmor.bNotAllowedByMielikki){
                SendMessageToPC(oPC,Colorize("r","Druids of Mielikki who don heavy metal armor loose their "+
                  "spellcasting ability, as per PHB page 34, while wearing the armor and for 24 hours after "+
                  "unequiping it."));
                SetDruidHasEquippedMetalArmor(oPC);
            }
        }
        int iStillSelling = GetLocalInt(oPC,"UNADJUSTED");
        if(!iStillSelling){
            SetLocalInt(oItem, "ADJUSTING", TRUE);
            SetLocalInt(oItem, "EQUIPPED", TRUE);
            DelayCommand(0.01,ExecuteScript("armor", oItem));
        }
    }
 
    // * This code runs when the item is unequipped
    // * Note that this event fires PCs only
    else if (nEvent ==X2_ITEM_EVENT_UNEQUIP)
    {
 
        oPC    = GetPCItemLastUnequippedBy();
        oItem  = GetPCItemLastUnequipped();
        int bIsMetalOverride = GetLocalInt(oItem, "IS_NOT_METAL");
        string sId = GetLocalString(oPC, "PWId");
        if (sId=="") return;
 
        int nDeafultHours = 24;
 
        struct armor stArmor = GetArmorStructById(oItem);
 
        if(stArmor.bIsMetal && !bIsMetalOverride && GetIsDruid(oPC) && !GetIsDM(oPC)){
            if(GetStringLowerCase(GetDeity(oPC))!="mielikki")
                SetDruidHasUnequippedMetalArmor(oPC, oItem);
            else if(stArmor.bNotAllowedByMielikki)
                SetDruidHasUnequippedMetalArmor(oPC, oItem);
        }
        int iStillSelling = GetLocalInt(oPC,"UNADJUSTED");
        if(!iStillSelling){
            SetLocalInt(oItem, "ADJUSTING", TRUE);
            SetLocalInt(oItem, "EQUIPPED", FALSE);
            DelayCommand(0.01,ExecuteScript("armor", oItem));
        }
    }
    // * This code runs when the item is acquired
    // * Note that this event fires PCs only
    else if (nEvent == X2_ITEM_EVENT_ACQUIRE)
    {
        oPC = GetModuleItemAcquiredBy();
        oItem  = GetModuleItemAcquired();
        int nACBonus = ACBonus(oItem);
        struct armor stArmor = GetArmorStructById(oItem);
        itemproperty ipWepTypevsArmorTypeMod;
 
        int bEntered = GetLocalInt(oPC,"ENTERED");
        if(!bEntered)
            IPRemoveMatchingItemProperties(oItem, ITEM_PROPERTY_AC_BONUS);
 
        int iStillSelling = GetLocalInt(oPC,"UNADJUSTED");
        if(!iStillSelling){
            SetLocalInt(oItem, "ADJUSTING", TRUE);
            SetLocalInt(oItem, "EQUIPPED", FALSE);
            DelayCommand(0.01,ExecuteScript("armor", oItem));
        }
    }
 
    // * This code runs when the item is unaquired
    // * Note that this event fires PCs only
    else if (nEvent == X2_ITEM_EVENT_UNACQUIRE)
    {
 
        oPC = GetModuleItemLostBy();
        oItem  = GetModuleItemLost();
 
        //Get the first itemproperty on the helmet
        itemproperty ipLoop=GetFirstItemProperty(oItem);
 
        //Loop for as long as the ipLoop variable is valid
        while (GetIsItemPropertyValid(ipLoop))
        {
            //If ipLoop is a damage bonu vs type or damage vulnerability property, remove it
            if ((GetItemPropertyType(ipLoop)==ITEM_PROPERTY_AC_BONUS_VS_DAMAGE_TYPE)||
                (GetItemPropertyType(ipLoop)==ITEM_PROPERTY_DAMAGE_VULNERABILITY))
                    RemoveItemProperty(oItem, ipLoop);
 
            //Next itemproperty on the list...
            ipLoop=GetNextItemProperty(oItem);
        }
    }
 
    //* This code runs when a PC or DM casts a spell from one of the
    //* standard spellbooks on the item
    else if (nEvent == X2_ITEM_EVENT_SPELLCAST_AT)
    {
 
        oPC = GetModuleItemLostBy();
        oItem  = GetModuleItemLost();
    }
}