Author Topic: Potions With Unique Power Scripts  (Read 503 times)

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« on: June 19, 2011, 07:44:17 pm »


               I am planning to add an underwater area to my module, however I am having some problems making potions of water breathing. I made the potions, and then I gave them the property: cast spell: unique power self only. I made some tag based scripts to run when the potions were activated. The tag script I made is an on activate script. It uses variables to determine when to run the damage script.
The damage script I made is an on enter script that does damage if the player has not drank a potion. However the potions did not work at all. There were no visual effects, and I took damage when entering the area trigger. I tried making a new item that wasn't a potion, and it worked fine.

My question is: How do I get an activate item script to work with a potion?

These are the scripts I used. I know using two scripts for activate item is not very efficient, but that is the way I know for now.

The event script:

#include "x2_inc_switches"
void main()
{
int nEvent =GetUserDefinedItemEventNumber();
switch (nEvent)
   {
   case X2_ITEM_EVENT_ACTIVATE:
ExecuteScript("ac_"+GetTag(GetItemActivated()),
OBJECT_SELF); break;
   case X2_ITEM_EVENT_EQUIP:
ExecuteScript("eq_"+GetTag(GetPCItemLastEquipped()),
OBJECT_SELF); break;
   case X2_ITEM_EVENT_UNEQUIP:
ExecuteScript("ue_"+GetTag(GetPCItemLastUnequipped())
, OBJECT_SELF); break;
   case X2_ITEM_EVENT_ACQUIRE:
ExecuteScript("aq_"+GetTag(GetModuleItemAcquired()),
OBJECT_SELF); break;
   case X2_ITEM_EVENT_UNACQUIRE:
ExecuteScript("ua_"+GetTag(GetModuleItemLost()),
OBJECT_SELF); break;
   case X2_ITEM_EVENT_SPELLCAST_AT:
ExecuteScript("sp_"+GetTag(GetModuleItemLost()),
OBJECT_SELF); break;
   case X2_ITEM_EVENT_ONHITCAST:
ExecuteScript("on_"+GetTag(GetSpellCastItem()),
OBJECT_SELF); break;
   }
}

This is my potion script. It adds a spell immunity so that it will show an icon to show that the potion effects are still active.


void main()
{
object oPC;
oPC = GetItemActivator();
int nInt;
nInt = GetLocalInt(oPC, "sot_waterbreath");
nInt += 1;
SetLocalInt(oPC, "sot_waterbreath", nInt);
object oTarget;
oTarget = oPC;
effect eEffect;
eEffect = EffectSpellImmunity(SPELL_COMBUST);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEffect, oTarget, 180.0f);
//Visual effects can't be applied to waypoints, so if it is a WP
//the VFX will be applied to the WP's location instead
nInt = GetObjectType(oTarget);
if (nInt != OBJECT_TYPE_WAYPOINT) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oTarget);
else ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), GetLocation(oTarget));
nInt = GetLocalInt(oPC, "sot_waterbreath");
nInt -= 1;
DelayCommand(180.0, SetLocalInt(oPC, "sot_waterbreath", nInt));
}

This is the script I used to cause damage to the player when not drinking a potion. There is a helm of water breathing too, which works fine, but it is a quest item and will not always be available. I made this script as an on enter script to test the items, however I think a heartbeat script for the area would be a better idea.

void main()
{
object oPC = GetEnteringObject();
if (!GetIsPC(oPC)) return;
if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) == "sot_WaterBreathHelm")
   return;
if (GetLocalInt(oPC, "sot_waterbreath")!= 0)
   return;
effect eEffect;
eEffect = EffectDamage(100, DAMAGE_TYPE_DIVINE, DAMAGE_POWER_ENERGY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oPC);
object oTarget;
oTarget = oPC;
//Visual effects can't be applied to waypoints, so if it is a WP
//the VFX will be applied to the WP's location instead
int nInt;
nInt = GetObjectType(oTarget);
if (nInt != OBJECT_TYPE_WAYPOINT) ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_WATER), oTarget);
else ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_WATER), GetLocation(oTarget));
FloatingTextStringOnCreature("You are drowning!", oPC);
}


I made these scripts with the script generator, so there is probably some things that are not needed. Will these scripts work with potions, or should I just use items instead? I could not make an area heartbeat script with the script generator, so I could use some help with that. 

I also encountered a problem with them not working in combat. Is it possible to modify the scripts to bypass the module on activate item script?

I looked at some of the script tutorials, but none of them mentioned potions or area heartbeat scripts.

Any help would be greatly appreciated.

Thank you.
               
               

               


                     Modifié par Sadira of Tyr, 19 juin 2011 - 06:51 .
                     
                  


            

Legacy_Alex Warren

  • Sr. Member
  • ****
  • Posts: 326
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #1 on: June 19, 2011, 08:15:12 pm »


               Try this script:

#include "x2_inc_switches"
void main()
{
   if(GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ACTIVATE)
   {
       object oPC = GetItemActivator();
       SetLocalInt(oPC, "sot_waterbreath", TRUE);
       ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSpellImmunity(SPELL_DROWN), oPC, 180.0f);
       ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oPC);
       DelayCommand(180.0, SetLocalInt(oPC, "sot_waterbreath", FALSE));
   }
}

it should have the same name as potions tag. (i didn't tested it, but it *should* work). also changed spell immunity from comburst to drown '<img'>

cleaned on enter:
void main()
{
   object oPC = GetEnteringObject();
   if(!GetIsPC(oPC))
       return;
   if(GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) == "sot_WaterBreathHelm")
       return;
   if(GetLocalInt(oPC, "sot_waterbreath"))
       return;

   effect eEffect = EffectDamage(100, DAMAGE_TYPE_DIVINE, DAMAGE_POWER_ENERGY);
   ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oPC);
   ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_WATER), oPC);
   FloatingTextStringOnCreature("You are drowning!", oPC);
}


and this is my proposition for area hb (my first area hb script ever!)

void main()
{
   object oTest = GetFirstObjectInArea(OBJECT_SELF);
    while(GetIsObjectValid(oTest))
   {
       if(GetIsPC(oTest) && !GetIsDM(oTest))
       {
           if(GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oTest)) != "sot_WaterBreathHelm"
           && !GetLocalInt(oTest, "sot_waterbreath"))
           {
               effect eEffect = EffectDamage(100, DAMAGE_TYPE_DIVINE, DAMAGE_POWER_ENERGY);
               ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTest);
               ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_PULSE_WATER), oTest);
               FloatingTextStringOnCreature("You are drowning!", oTest);
           }
       }
       oTest = GetNextObjectInArea(OBJECT_SELF);
   }
}
               
               

               


                     Modifié par Alex Warren, 19 juin 2011 - 07:31 .
                     
                  


            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #2 on: June 19, 2011, 08:46:25 pm »


               I will try these. Thank you very much. 'Image
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #3 on: June 19, 2011, 09:45:49 pm »


               Well, I put the scripts in the module and tested them. They worked quite well, and your first heartbeat script worked fine.

However there was one little problem. I tried drinking a second potion before the first one ran out. When the first one ran out, it cancelled the effects of the second potion as well. Other than that, it worked fine though.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #4 on: June 19, 2011, 10:01:53 pm »


               That's due to the delayed integer deactivating.  When the first potions duration expires it unsets the variable the second one set as well.  Without an effect set that you can track later there aren't many other options for it though, sadly.
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #5 on: June 19, 2011, 10:40:47 pm »


               Ah ok, thank you. 'Image
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #6 on: June 20, 2011, 02:24:55 am »


               There are ways around the problem with the second potion. Instead of setting a variable to TRUE and the using a delay command to set it FALSE you could just set an int like 30 for example. And each time a potion is consumed it adds 30 more. And then let the area or module or some other objects HB count it down. So every 6 seconds(kind of) the int is reduced by one. If the player drank one potion that would give you about 180 seconds just like your delay.

Just a thought.
               
               

               


                     Modifié par GhostOfGod, 20 juin 2011 - 01:28 .
                     
                  


            

Legacy_Alex Warren

  • Sr. Member
  • ****
  • Posts: 326
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #7 on: June 20, 2011, 09:19:07 am »


               Yeah, sorry - didn't noticed that. This should work though '<img'>

#include "x2_inc_switches"

void WaterBreathEnd(object oPC)
{
    int i = GetLocalInt(oPC, "sot_waterbreath") - 1;
    SetLocalInt(oPC, i);
}

void main()
{
    if(GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ACTIVATE)
    {
        object oPC = GetItemActivator();
        int i = GetLocalInt(oPC, "sot_waterbreath") + 1;
        SetLocalInt(oPC, "sot_waterbreath", i);
        ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSpellImmunity(SPELL_DROWN), oPC, 180.0f);
        ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oPC);
        DelayCommand(180.0, WaterBreathEnd(oPC));
    }
}

Also the effect of water breathing potion in PnP would last at least 10 hours (3rt lvl spell, 2h/lvl) so in NWN this would be 1200.0 - 180.0 seems a bit too short for me ;p
               
               

               


                     Modifié par Alex Warren, 20 juin 2011 - 08:27 .
                     
                  


            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #8 on: June 20, 2011, 10:37:45 am »


               

Alex Warren wrote...

Yeah, sorry - didn't noticed that. This should work though '<img'>

#include "x2_inc_switches"

void WaterBreathEnd(object oPC)
{
int i = GetLocalInt(oPC, "sot_waterbreath") - 1;
SetLocalInt(oPC, i);
}

void main()
{
if(GetUserDefinedItemEventNumber() == X2_ITEM_EVENT_ACTIVATE)
{
object oPC = GetItemActivator();
int i = GetLocalInt(oPC, "sot_waterbreath") + 1;
SetLocalInt(oPC, "sot_waterbreath", i);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectSpellImmunity(SPELL_DROWN), oPC, 180.0f);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_SMOKE_PUFF), oPC);
DelayCommand(180.0, WaterBreathEnd(oPC));
}
}

Also the effect of water breathing potion in PnP would last at least 10 hours (3rt lvl spell, 2h/lvl) so in NWN this would be 1200.0 - 180.0 seems a bit too short for me ;p


Well, an illithid is selling the potions, and I guess he waters them down, lol. 'Image

You never can trust those guys lol, but I may change them to 5 or 10 minutes depending on how hard the area will be.

I will try this new script. Will the heartbeat script need any changes?

Thank you for helping me. 'Image
               
               

               
            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #9 on: June 20, 2011, 10:59:34 am »


               Well, I tried the script, but it did not compile.

For this line:

SetLocalInt(oPC, i);            (declatration does not match parameters.)


Thank you.
               
               

               
            

Legacy_mwplayer

  • Newbie
  • *
  • Posts: 38
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #10 on: June 20, 2011, 11:14:19 am »


               He forgot to put the string in.

This is how a SetLocalInt is set up:

SetLocalInt(object oObject, string sVarName, int nValue);

what yours looked like was

SetLocalInt(oPC, i); 

That's what the error meant by "Declaration does not match parameters". Since you already had a string, all you needed to do was to put it in there.

I changed it to this and it could compile:

SetLocalInt(oPC, "sot_waterbreath", i);

Btw Sadira, I wonder if you remember me :happy:
               
               

               


                     Modifié par mwplayer, 20 juin 2011 - 10:27 .
                     
                  


            

Legacy_Sadira of Tyr

  • Sr. Member
  • ****
  • Posts: 299
  • Karma: +0/-0
Potions With Unique Power Scripts
« Reply #11 on: June 20, 2011, 11:34:48 pm »


               The script works great now. Thanks guys!  'Image


mwplayer wrote...
Btw Sadira, I wonder if you remember me :happy:


Of course I remember you. You and your friend Cobra, lol. I miss you guys.

If you ever want to come back, I would welcome you and your friends. 'Image